上一篇我们聊到了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. Beta冲刺 —— 5.28

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.组员一起学习Git分支管 ...

  2. Chisel3 - util - Lookup

    https://mp.weixin.qq.com/s/g85Si6n37D9PYfR5hEoRQQ     实现一个查找逻辑.   参考链接: https://github.com/freechips ...

  3. Java实现 蓝桥杯VIP 基础练习 龟兔赛跑预测

    题目描述 话说这个世界上有各种各样的兔子和乌龟,但是 研究发现,所有的兔子和乌龟都有一个共同的特点--喜欢赛跑.于是世界上各个角落都不断在发生着乌龟和兔子的比赛,小华对此很感兴趣,于是决定研究不同兔 ...

  4. Java实现 LeetCode 225 用队列实现栈

    225. 用队列实现栈 使用队列实现栈的下列操作: push(x) – 元素 x 入栈 pop() – 移除栈顶元素 top() – 获取栈顶元素 empty() – 返回栈是否为空 注意: 你只能使 ...

  5. Java实现高效便捷还容易懂的排序算法

    PS:我现在越来越认为排序大法是,很深的算法了,就是简单的几个步骤,网上的大佬们能给你玩出花来(ง •_•)ง public class zimuzhenlie2 { public static vo ...

  6. Java实现完美洗牌算法

    1 问题描述 有一个长度为2n的数组{a1,a2,a3,-,an,b1,b2,b3,-,bn},希望排序后变成{a1,b1,a2,b2,a3,b3,-,an,bn},请考虑有没有时间复杂度为O(n)而 ...

  7. RPM包管理-yum在线管理

    常用yum命令 查询 查询所有可用软件包列表,yum list 搜索所有和关键字相关的软件包,yum search 关键字 安装 yum -y install 包名,其中,-y 表示自动回答yes 升 ...

  8. 记一次Docker中Redis连接暴增的问题排查

    周六生产服务器出现redis服务器不可用状态,错误信息为: 状态不可用,等待后台检查程序恢复方可使用.Unexpected end of stream; expected type 'Status' ...

  9. 安装fail2ban,防止ssh爆破及cc攻击

    背景:之前写过shell脚本防止服务器ssh爆破,但是对于服务器的cpu占用较多,看来下资料安装fail2ban 可以有效控制ssh爆破 1:fail2ban 安装(环境:centos6  宝塔) y ...

  10. Python 3中,import win32com.client 出错

    在 import win32com.client 时,出现了界面: Traceback (most recent call last): File "<pyshell#1>&qu ...