1. 事务

菜鸟教程:mysql事务的基本介绍

2. 事务的隔离级别

  • mysql事务的隔离级别:定义了事务与事务之间的隔离程度;
  • mysql有四种事务的隔离级别:

3. 由隔离性引发的问题

  • 脏读、不可重复度、幻读

4. 演示四种隔离级别

  • 注意:我的mysql是5.7.19,不同版本的命令会有些微调

  • 首先需要开启两个会话,才能演示不同事务之间的隔离性

  • 分别查看两个会话中事务的隔离级别
    select @@tx_isolation;
    一般默认的都是【可重复读】隔离级别

  • 把一个会话的事务隔离级别改变,依次演示各种问题

    SET SESSION TRANSACTION ISOLATION LEVEL 
    READ UNCOMMITTED/*读未提交---隔离性低*/
    READ COMMITTED/*读已提交---隔离性中*/
    REPEATABLE READ/*可重复读---隔离性高*/
    SERIALIZABLE/*可串行化---隔离性最高*/
    
  • 现在:左边是【可重复读级别】、右边是【读未提交级别

  • 两个会话都开启事务,因为隔离性就是和事务有关的,离开事务不谈隔离级别

  • 建立一张表account(id,name,balance)

    我们可以看到,在【读未提交】会话中建立一张表,在【可重复读】会话中是可以感知到这张表的创建的,隔离的仅仅是对表的dml操作(delete update insert),对表的创建是不隔离的;

  • 在左边插入数据,并且还没有提交事务,右边就可以查询到,我么就说右边的是【脏读】

  • 我们可以做适当推理,在左边事务未提交时,右边都可以感知到,那么一旦左边操作提交,那么右边就一定是感应得到的,无论是删除、修改还是插入;这就说明,【脏读】是非常严重的问题,出现脏读就一定会出现【不可重复读】【幻读】,咱们来试试:

  • 由此证明了【read uncommitted】 隔离级别会有脏读、不可重复读、幻读

  • 接下来,把右边设置成【read committed】隔离级别,继续试验:
    提醒: 隔离性的体现,一定要在事务中,因此start transaction;是必不可少的;

    - 上述证明,【read committed】隔离级别没有脏读,但依然有不可重复读、幻读

  • 接下来提交事务,双边均提交事务,把右边设置成【可重复读级别】:

    上图证明了没有【脏读】的现象;
    上图证明了没有【幻读】、【不可重复读】现象

  • 需要强调的是,事务一旦提交,那么不同会话之间的数据便一致了,因为隔离性针对的是事务:

  • 下面演示【可串行化】隔离级别

  • 它与【可重复读】的主要区别是,可串行化会给表加锁,一旦一个事务加入可串行化序列,那么它可操作的表必须是空闲的表,若某个表正在被其他事务操作,那么可串行化事务便会一直等待,直到那个事务结束,或者查询超时:
    可以观察到,右边会话的查询操作等待了很久,直到左边commit后,才有结果,串行化效率比较低,但适用于多个会话之间需要数据同步互通的系统,虽然需要等待一些时间,但实现了所有会话数据的一致性;

  • 可串行化事务会出现两种情况:
    1.A会话开启,事务开启并设置为可串行化,先操作某个表,事务仍在继续;此时另一个事务B,不管是什么隔离级别,再操作此表时,就只能selelct,不能进行dml操作
    2.A会话开启,事务开启并设置为可串行化,但是事务B抢先操作了那张表,结果A就不能操作这张表了,连select语句都不行!这是不一样的两种情况,注意区分;

5. 隔离级别查询设置命令

-- 查询当前会话隔离级别
SELECT @@tx_isolation;
-- 查询系统隔离级别(用户登陆时默认的隔离级别)
SELECT @@global.tx_isolation;
-- 设置当前会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL 
	READ UNCOMMITTED/*读未提交---隔离性低*/
	READ COMMITTED/*读已提交---隔离性中*/
	REPEATABLE READ/*可重复读---隔离性高*/
	SERIALIZABLE/*可串行化---隔离性最高*/
	
-- 设置系统当前系统隔离级别
SET GLOBAL TRANSACTION ISOLATION LEVEL 
	READ UNCOMMITTED/*读未提交---隔离性低*/
	READ COMMITTED/*读已提交---隔离性中*/
	REPEATABLE READ/*可重复读---隔离性高*/
	SERIALIZABLE/*可串行化---隔离性最高*/

更多推荐

mysql事务隔离级别