MySQL-问个关于MySQL的事务与锁策略相关的问题
考虑以下场景:
表A引擎为innodb,现有两个事务T1,T2,默认隔离级为Repeatable Read,autocommit = 1
T1:
{
1:start transaction;
2:update A set name = 'ABC' where ID = 1;
3:select * from A where ID = 1;
4:COMMIT;
}
T2:
{
1:select * from A where ID = 1;
}
请问: 当T1执行完第二步后,执行T2需要等待吗?执行T1中的第三步需要等待吗?希望能说下原理。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在mysql 5.5.24中实际测试的结果:
(表A引擎为innodb,现有两个事务T1,T2,默认隔离级为Repeatable Read,autocommit = 1)
T1 start transaction;确实开启了一个事务,如果不commit, T2是无法读到update的值的。
回到楼主的的问题,我的理解,mysql在repeatable read和read committed级别上,用的是MVCC,读操作不会被block (Consistent Nonlocking Reads),只有不同事务中对同一记录的更新操作会被block。
http://dev.mysql.com/doc/refman/5.6/en/innodb-consistent-read.html
autocommit置1的条件下启动transaction是件很奇怪的事情。
因为设置了autocommit = 1,那t1,t2会自动提交,因此没有等待发生。
如果设置autocommit = 0,那情况就会复杂一些。详细参考这里 next-Key lock
基本原理:
MySQL INNODB 使用了next-Key Lock 算法,避免了不可重复读的现象。在此算法下,对索引的扫描,不仅仅是锁住扫描到的索引,而且还锁住了这些索引覆盖的范围(gap).
1. T1执行 update A set name = 'ABC' where ID > 10; 没有提交.
2.1 如果 T2执行 Update A set name = 'DDD' where ID<15,那T2就会等待T1事务结束才开始执行。
2.2 如果T2执行 Update A set name = 'DDD' where ID<10, 那ok,T1,T2不要等待。
希望有所帮助,同时如果有不对,请网友指出!