本文通过实例展示MySQL事务的四种隔离级别。

    1 概念阐述

    1)Read Uncommitted(读未提交)

       其他事务的在未提交的改动下,当前事务可以察觉。

    2)Read Committed(读提交)

       其他事务在提交改动之后,当前事务可以察觉,如果其他事务未提交改动,那么不会察觉。

    3) Repeatable Read(可重复读)

       其他事务提交了改动,并且当前事务也提交的操作,之后才可以察觉改动。

    4) Serializable(可串行化的)

       通过加锁方式,仅仅保持一个事务执行更新操作,如果其他事务执行更行操作,那么将处于阻塞

    等待状态。


    2 实例展示

    2.1 如何查询当前MySQL的事务隔离级别

    【MySQL之事务隔离级别】_第1张图片

    MySQL默认隔离级别是Repeatable Read(可重复读)

    2.2 设置当前会话的隔离级别

    【MySQL之事务隔离级别】_第2张图片

    2.3 Read Uncommitted 隔离级别效果展示

    1.A,B两个事务,将A事务设置为Read Uncommitted事务隔离级别,当B事务,做修改后未提交,A事务可以发现B事务的修改内容。

    2.当A事务修改某条记录时,B也修改某条记录,会出现B阻塞等待现象,也就是说A事务修改会具有行级锁。

    (A事务)

    【MySQL之事务隔离级别】_第3张图片

    (B事务修改数据,但不提交)

    【MySQL之事务隔离级别】_第4张图片

    (A事务可以察觉B事务修改的数据)

    【MySQL之事务隔离级别】_第5张图片

    从上述过程可以发现,在Read Uncommitted隔离级别下,事务之间的修改会相互察觉,因此容易出现脏读现象。

    而且此时事务A:update counter set value=1002 where id=1,但不提交事务;事务B也执行update counter set value = 1004 where id = 1;会阻塞等待直到超时。原因是因为事务A执行时,锁住了id=1的这行记录,因此其他事务必须等待处理完毕再执行;但是其他事务可以处理id!=1的记录。

    2.4 Read Committed 隔离级别效果展示

    1. A、B两个事务,假设A事务的隔离级别为Read Committed,那么B事务在执行commit之后,A事务可以发现B的修改。

    2. 与Read UnCommitted一样,都存在行级锁的现象。

    (A事务)

    【MySQL之事务隔离级别】_第6张图片

    (B事务更新但未提交)

    【MySQL之事务隔离级别】_第7张图片

    (B事务提交后,A事务可以发现B的修改)

    【MySQL之事务隔离级别】_第8张图片

    2.5 Repeatable Read(可重复读)

    1. A、B事务,A事务为Repeatable Read,当事务B修改后提交,A仍然无法察觉B的修改效果,而当A事务也提交之后,才可以察觉B的修改。

    2. 同样存在行级锁的锁定

    (A事务)

    【MySQL之事务隔离级别】_第9张图片

    (B事务修改并提交,A事务仍然无法发觉B的修改)

    【MySQL之事务隔离级别】_第10张图片

    (A事务也提交后,可以发现B的修改)

    【MySQL之事务隔离级别】_第11张图片

    2.6 Serializable(可串行化的)

    1. A、B事务,A事务为Serializable,那么B不能执行任何更新操作,因为A会获取表级锁,使得其他事务无法访问。

    (A事务)

    【MySQL之事务隔离级别】_第12张图片

    (B事务修改操作,无法执行)

    【MySQL之事务隔离级别】_第13张图片


    3 总结

    在MySQL中默认采用可重复读(Repeatable Read)隔离级别。关于隔离级别的其他知识点以及更细微的介绍,本文不做过多介绍,仅仅介绍基本的概念和理解,如果有兴趣的伙伴,可以考虑按照我这种模式,不断实验。