第十章:第15节 MySQL进阶篇——Repeatable Read隔离级别下锁效果模拟演示

更新于:2017-08-31 11:05:24

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X),通过上节的了解,只有加了X锁的事务可读可写,其他事务不能读不能写,我们来模拟验证下。


1)模拟的方式,开启两个cmd窗口,就代表同时有两个客户端(session)连接MySQL服务。当前的隔离级别是“RR(Repeatable Read”,MySQL默认的“可重读”。


1.png


2)进入测试数据库,开启事务,(左边)先执行一条普通不加锁的select语句,然后(右边)紧跟着执行同样的select语句。


1.png


两边都能正常获取数据,因为都是不加锁的SQL语句,所以相互不影响。


3)接下来(左边)先执行select加X锁,然后再执行(右边)的语句。


1.png


(左边)select语句执行正常,看(右边)普通的select语句是成功的,可加锁的select语句执行后没有反应,直接卡那了,过一会就会报错:


1.png


锁等待超时。因为(右边)想要获取相同数据集的排他锁,(左边)占着一直获取不到,一定时间后就会超时。


通过上面的例子,是否可以感觉到锁的存在。


4)(左边)的事务楠神还没有提交,排他锁依然存在,楠神在(右边)再执行一个更新操作。


1.png


update语句自带排他锁功能,同样获取不到X锁报超时错误。


5)(右边)重新执行下update语句,(左边)commit提交


1.png


(右边)update语句还是卡在那,当(左边)commit一提交,(右边)立马就获取到了X锁,OK,更新成功。


6)(右边)更新完数据后,事务暂时没有提交,楠神在(左边)暂时不开启事务,执行下普通的select查询


1.png


咦?(右边)明明把“age”改成55了,怎么还是34。


7)(右边)提交下事务,然后(左边)再执行下select语句


1.png


这次是55了。所以说一个事务(A)未提交,其他事务是看不到(A)事务修改的数据的。


8)左右两边都再同时开启事务,执行select语句


1.png


9)(左边)先执行update语句,(右边)再执行加了X锁的select语句,(左边)提交


1.png


(右边)虽然身在事务中,可加了X锁select还是可以获取到(左边)提交事务后获取的数据。


10)假如说同样的条件下,(右边)未提交事务前最后一步执行的是普通select语句:


1.png


还是44,然后楠神在接着执行加X锁的和普通的select语句


1.png


哈哈,是不是这个地方很困惑。


普通的select语句满足了“可重复读”,也就是只要是事务没有结束,同样的普通select语句不论什么时候读取的数据都是一致的(前提是在此事务内没有对相关的数据做修改,其他事务修改了相关数据不受影响),加了锁(X锁、S锁)的select语句就不一样了,获取的数据都是最新的。


本节学习代码》》》