上一篇我们聊到了mariadb的锁,以及怎么手动加锁和解锁等等,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13196905.html;今天我们来聊一聊mariadb的事务隔离级别;在前边的随笔中,我们提到到了mysql的存储引擎,常用的有MyISAM和innodb,其中myisam不支持事务,innodb支持事务;所以我们常说的事务是针对innodb存储引擎来说的;所谓事务就是在我们在执行大批量语句时,为了保证数据库的完整性,要么语句全部执行,要么语句全部不执行;所以事务必须满足ACID这是个条件;A表示Atomicity,原子性,也是不可分性;C表示Consistency,一致性;I表示Isolation,隔离性,又称独立性;D表示Durability,持久性;所谓原子性,就是事务中执行的语句要么全部执行,要么全部不执行,如果事务在中途发生错误,那么前面执行过的语句将会回滚到事务前;一致性指的是在执行事务之前和事务执行完成后的数据库状态是完整的;也就是说我们执行的语句都按照我们预想的结果执行了;隔离性指数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。持久性指的是,事务执行完成后,对数据的修改是永久的;

  接下来我们来说说怎么在mariadb中开启事务吧

  用户手动开启事务用start transaction 或者使用begin语句开启事务;

  提示:以上红框中的语句就表示手动开启一个事务;这里需要注意一点,对于mysql来讲,默认在命令行执行的语句都是自动提交事务的;也就是说默认情况下我们在mysql shell中执行的语句它默认也会开启一个事务,但我们语句执行完成后,它会自动把该事务提交;所以我们手动开启一个事务可以使用start transaction 语句 或者begin 或者执行set autocommit=0来关闭自动提交事务;

  提示:提交事务用commit 语句,表示结束当前事务;当然结束当前事务也可以用rollback语句,表示回滚到事务之前的状态;回滚以后事务也就结束了;

  SAVEPOINT identifier:创建一个保存点,一个事务中可以存在多个保存点,回滚时我们可以指定回滚到某个点上;

MariaDB [first_db]> begin;
Query OK, 0 rows affected (0.000 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
+------+----------+------+
2 rows in set (0.001 sec) MariaDB [first_db]> insert into test_tb values (3,"lisi",23);
Query OK, 1 row affected (0.002 sec) MariaDB [first_db]> savepoint one;
Query OK, 0 rows affected (0.001 sec) MariaDB [first_db]> insert into test_tb values (4,"wangwu",25);
Query OK, 1 row affected (0.001 sec) MariaDB [first_db]> savepoint two;
Query OK, 0 rows affected (0.000 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
| 3 | lisi | 23 |
| 4 | wangwu | 25 |
+------+----------+------+
4 rows in set (0.001 sec) MariaDB [first_db]> rollback to one;
Query OK, 0 rows affected (0.001 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
| 3 | lisi | 23 |
+------+----------+------+
3 rows in set (0.001 sec) MariaDB [first_db]>

  提示:存在多个保存点,如果回滚到前边的点以后,后面的保存点就没有了;

  接下来看看事务的隔离级别

  对于mysql数据库 innodb存储引擎支持的事务隔离级别有4中,READ-UNCOMMITED:读未提交;这表示事务还没有结束,其他用户或进程是可以实时的读到事务中对数据的改变,因为事务还没提交,所以我们认为其他用户或进程读到的数据就是一个不准确的数据,通常我们把这种叫脏读;READ-COMMITTED:读提交;这表示只有事务提交后,其他用户或进程才可以读到事务修改后的数据;这种事务隔离级别就要比前面的隔离级别要高一点,读到的数据也要精准一点;这种隔离级别就是只要事务A提交了,在其他事务里就可以读取到事务A修改后的数据;通常这种我们叫不可重复读,不可重复读表示在其他事务中,读到的数据是根据事务A是否提交有关系;REPEATABLE-READ:可重复读,这表示在A事务中修改后的数据,在B中事务上不可见的,即便A中事务已经提交,B中事务没有提交,那么在B中的事务中读到的还是A事务修改前的数据;只有当事务B结束后才能读到A事务修改后的数据;所以通常我们把这种方式也叫幻读,给人一种幻觉的感觉;SERIALIZABLE:串行化;这种隔离级别是最高的,但同时并发访问也是最差的,它表示事务A和事务B是顺序执行的,什么意思呢,就是说事务B必须要等到事务A完成后才可以执行;

  关闭自动提交功能

MariaDB [first_db]> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.001 sec) MariaDB [first_db]> set @@session.autocommit=0;
Query OK, 0 rows affected (0.001 sec) MariaDB [first_db]> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.001 sec) MariaDB [first_db]>

  提示:以上语句表示设定当前会话关闭自动提交功能,关闭此会话它将恢复原有设定;

  设置事务A的隔离级别为read-uncommitted

  提示:事务隔离级别字串要加引号,否则会提示语法错误

  设置会话B的隔离级别为read-uncommitted

  在事务A中修改表中数据,在会话B中查看表中数据,看看是否在会话B中看到修改后的数据?

MariaDB [first_db]> BEGIN;
Query OK, 0 rows affected (0.000 sec) MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ |
+------------------------+
1 row in set (0.001 sec) MariaDB [first_db]> set @@session.tx_isolation='read-uncommitted';
Query OK, 0 rows affected (0.001 sec) MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED |
+------------------------+
1 row in set (0.001 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
+------+----------+------+
2 rows in set (0.001 sec) MariaDB [first_db]> insert into test_tb values(2,"xiaohong",33);
Query OK, 1 row affected (0.001 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
| 2 | xiaohong | 33 |
+------+----------+------+
3 rows in set (0.001 sec) MariaDB [first_db]>

  提示:在事务A中插入数据在当前事务中是可以正常看到数据的变化;

  提示:可以看到在会话B上是可以正常看到事务A中数据的修改;

  提示:从上面的信息可以看到,当事务A中的修改操作回滚时,在会话B中是可以查看到回滚后的数据;这也意味这在会话B中读到的数据不是很准确;

  设置事务A的事务隔离级别为read-committed

  设置会话B的事务隔离级别为read-committed,然后在事务A上修改数据,不提交,看看会话B上是否可以看到?

MariaDB [first_db]> start transaction;
Query OK, 0 rows affected (0.001 sec) MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED |
+------------------------+
1 row in set (0.001 sec) MariaDB [first_db]> set @@session.tx_isolation='read-committed';
Query OK, 0 rows affected (0.001 sec) MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-COMMITTED |
+------------------------+
1 row in set (0.001 sec) MariaDB [first_db]> select @@session.autocommit;
+----------------------+
| @@session.autocommit |
+----------------------+
| 0 |
+----------------------+
1 row in set (0.001 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
+------+----------+------+
2 rows in set (0.001 sec) MariaDB [first_db]> insert into test_tb values(3,"wangwu",43);
Query OK, 1 row affected (0.001 sec) MariaDB [first_db]> select * from test_tb;
+------+----------+------+
| id | name | age |
+------+----------+------+
| 1 | xiaoming | 44 |
| 2 | zhangsan | 16 |
| 3 | wangwu | 43 |
+------+----------+------+
3 rows in set (0.001 sec) MariaDB [first_db]>

  在会话B中查看test_tb表,看看是否有能看到修改后的数据?

  提示:在会话B中可以看到的test_tb表中的数据还是事务A开始前的数据;

  提交事务A,看看会话B是否能够看到修改后的数据呢?

  提示:可以看到当事务A提交以后,在会话B中就可以看到事务A中修改后的数据;

  设置事务A的事务隔离级别为repeatable-read

MariaDB [first_db]> begin;
Query OK, 0 rows affected (0.000 sec) MariaDB [first_db]> set @@session.tx_isolation='repeatable-read';
Query OK, 0 rows affected (0.000 sec) MariaDB [first_db]> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| REPEATABLE-READ |
+------------------------+
1 row in set (0.000 sec) MariaDB [first_db]>

  关闭事务B的自动提交功能并设置事务B的隔离级别为repeatable-read

  在事务A中修改数据,并提交,看看在事务B中是否能看到修改后的数据?

  在事务B中查看test_tb表中的数据,看看是否有变化呢?

  提示:可以看到在事务B中无论怎么查看数据都是没有发生变化;

  提交事务B在查看数据看看是否有变化?

  提示:可以看到当事务B提交以后,再次查看表中数据,就可以看到事务A更改以后的表数据了;

  设置会话A的事务隔离级别为serializable

  设置会话B的事务隔离级别为serializable

  在事务A,事务B中更新表中同一条数据,看看会发生什么?

  提示:在事务B中成功修改了第一条数据;

  提示:在事务A上就不能修改第一条数据了,那我们在事务A上是否可修改第二条数据呢?

  提示:可以看到第二条数据是能够修改的;

  提交事务B,看看A事务上是否可以修改第一条数据呢?

  提示:提交了事务B以后,在会话B上再次查看test_tb表中的数据,发现执行不了,原因是事务A修改了第二条数据,还未完成事务,所以一直阻塞;

  在事务A上修改第一条数据,看看是否可修改?

  提示:提交了事务B以后,在事务A上还是不能够修改第一条数据;原因是事务A修改了第二条数据,事务还没有结束,所以第三个事务就无法执行,所以我们在会话B上是不能够查看数据,因为默认情况查看数据也会启动一个事务;

  结束事务A,在会话B上看看是否可查询?

  提示:回滚了事务A,事务A也就结束了;在事务B中修改的数据,在事务A上做回滚,是回滚不回去的;这说明回滚操作只针对当前事务;

  提示:结束了事务A以后,在会话B上就可以正常查看test_tb上的数据了;

  以上就是在mariadb数据库上的事务的四种隔离级别的区别;从上面的演示可以看到,串行化的隔离级别最高,但是并发连接也是最差的,因为它必须要等到前一个事务结束后才可以执行后面的事务;其次就是可重读,可重读必须是两个事务都结束以后才可以看到真实修改后的数据;再其次就是不可重读,读提交,这种隔离级别必须是一方事务提交以后其他事务才可以读到真实修改数据;而隔离级别最低就是对未提交,这种隔离级别只要是事务中修改了,其他事务上就能够读到相应的数据;当然这种读到的数据也是最不靠谱的;

Mariadb之事务隔离级别的更多相关文章

  1. MySQL/MariaDB中的事务和事务隔离级别

    本文目录:1.事务特性2.事务分类 2.1 扁平事务 2.2 带保存点的扁平事务 2.3 链式事务 2.4 嵌套事务 2.5 分布式事务3.事务控制语句4.显式事务的次数统计5.一致性非锁定读(快照查 ...

  2. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  3. 30分钟全面解析-SQL事务+隔离级别+阻塞+死锁

    以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化.  本系列主要是针对T-SQL的总结. [T-SQL基础]01.单表查询-几道sql查询题 [T-SQL基础] ...

  4. SQL Server 事务隔离级别详解

    标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设置数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一 ...

  5. InnoDB事务隔离级别

    转载于:http://blog.csdn.net/wudongxu/article/details/8623610 SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的 ...

  6. 1031MySQL事务隔离级别详解

    转自http://xm-king.iteye.com/blog/770721 SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的.低级别的隔离级一般支 ...

  7. 对于大于8046 bytes的行,RCSI/SI事务隔离级别无效

    自SQL Server 2005起,我们有了READ COMMITTED SNAPSHOT ISOLATION level (RCSI) 和SNAPSHOT ISOLATION level (SI)两 ...

  8. (转)SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)

    六.各种事务隔离级别发生的影响 修改数据的用户会影响同时读取或修改相同数据的其他用户.即这些用户可以并发访问数据.如果数据存储系统没有并发控制,则用户可能会看到以下负面影响: · 未提交的依赖关系(脏 ...

  9. (转)SQL SERVER的锁机制(三)——概述(锁与事务隔离级别)

    五.锁与事务隔离级别 事务隔离级别简单的说,就是当激活事务时,控制事务内因SQL语句产生的锁定需要保留多入,影响范围多大,以防止多人访问时,在事务内发生数据查询的错误.设置事务隔离级别将影响整条连接. ...

随机推荐

  1. oeong.xyz

    兴趣使然而搭的小破站:oeong.xyz

  2. RocketMQ系列(一)基本概念

    RocketMQ是阿里出品的一款开源的消息中间件,让其声名大噪的就是它的事务消息的功能.在企业中,消息中间件选择使用RocketMQ的还是挺多的,这一系列的文章都是针对RocketMQ的,咱们先从Ro ...

  3. Java实现 LeetCode 342 4的幂

    342. 4的幂 给定一个整数 (32 位有符号整数),请编写一个函数来判断它是否是 4 的幂次方. 示例 1: 输入: 16 输出: true 示例 2: 输入: 5 输出: false 进阶: 你 ...

  4. Java实现 洛谷 P1055 ISBN号码

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public ...

  5. 关于uniapp获取当前距离屏幕顶部的距离

    onPageScroll(e){ console.log(e); }

  6. jenkins 添加用户管理权限

    一.前言 小组开会通知 想把jenkins 构建的权限给开发,这样的话效率会增加.运维也不必每次帮助开发去构建发布. 1.规划 jenkins 四个项目分别对应三个人负责.项目下的只负责 CI.UAT ...

  7. transport方式连接Elasticsearch6.2.3

    连接ES有3中方式: ①transport方式 ②rest方式 ③JEST方式(第三方) 我自己项目使用第一种方式,代码和配置如下: 1.引入依赖 <dependency> <gro ...

  8. 常见ie9兼容问题

    公司项目要求需要兼容ie9,开发过程中遇到了许多问题,在这里记录一下,希望可以帮到其他需要的小伙伴. 浏览器兼容性问题无外乎三点,css样式兼容.JavaScript兼容及h5部分标签的兼容.主要介绍 ...

  9. LeetCode 76,一题教会你面试算法时的思考套路

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第45篇文章,我们一起来看看LeetCode的76题,最小窗口子串Minimum Window Substrin ...

  10. 跟着视频学python,Day1

    python介绍 发展史 安装 Hello World程序 变量 用户输入 模块初识 数据类型初识 条件表达式if...elif...else 循环表达式while 循环表达式for python介绍 ...