MySQL可重复读采坑记录-对事务B进行更新时,事务A提交的更新会不会影响到事务B

两种情况:

一、

1、开启事务A,更新id为3的这一行的数据,事务A不提交。

2、开启事务B,也更新id为3的这一行数据,此时事务B被阻塞在更新语句,等待事务A释放这一行的锁(事务A要释放着一行的锁,只有事务A提交过着回滚才行)。

二、

具体请看博客:https://www.cnblogs.com/Allen-win/p/8283102.html

1、开启事务A,设更新id为3的这一行数据,

2、在事务A提交或者回滚之前开启事务B,

3、此时事务A提交。数据更新到数据库。

4、此时在事务B中,再查询id为3的这一行数据,还是事务A未修改前的数据(可重复读),然后事务B也更新id为3的这一行数据为另一个值。提交事务B,数据更新到数据库。。

此时事务B对id为3这一行的更新会覆盖事务A对id为3这一行的更新。即其他事务在事务B提交后再查询id为3的这一行数据都是事务B所更新的值。。事务A就像没有对id为3更新过一样。

总结:

上面update其实就是持有对id为3这一行的写锁,其他事务中如果想要获取该行数据的读锁或者写锁,那么就会被阻塞。

只有当写锁被释放(事务结束),其他事务才能再次获的得该行的读锁或者写锁。

注意,会阻塞的是其他事务要获取读锁或者写锁的操作。。。而单纯select是不用获取任何锁的(读锁也不用),如果select要获取读锁或者写锁,那么就需要添加lock in share mode或者for update。

锁机制:

InnoDB实现了以下两种类型的行锁。

  • 共享锁(s):又称读锁。允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。
  • 排他锁(X):又称写锁。允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁。

  • 对于共享锁大家可能很好理解,就是多个事务只能读数据不能改数据。 
    对于排他锁大家的理解可能就有些差别,我当初就犯了一个错误,以为排他锁锁住一行数据后,其他事务就不能读取和修改该行数据,其实不是这样的。排他锁指的是一个事务在一行数据加上排他锁后,其他事务不能再在其上加其他的锁。mysql InnoDB引擎默认的修改数据语句:update,delete,insert都会自动给涉及到的数据加上排他锁,select语句默认不会加任何锁类型,如果加排他锁可以使用select …for update语句,加共享锁可以使用select … lock in share mode语句。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。

部分内容来自于:https://www.cnblogs.com/leedaily/p/8378779.html

发布了144 篇原创文章 · 获赞 36 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_36951116/article/details/103871915
今日推荐