mysql lock in share mode 容易死锁

JPA+Hibernate 锁 LockModeType.PESSIMISTIC_READ,容易出现死锁的情况,资料记录


情景一

LOCK IN SHARE MODE is not a good solution because if two users read the counter at the same time, at least one of them ends up in deadlock when it attempts to update the counter

如果两个客户端(事务)同时执行同一个查询,都进行更新时,至少其中一个会已死锁结束


实验: 开启两个mysql客户端


1 分别执行如下语句;


set autocommit=0;

begin;

 select * from test_concurrence where id='1' lock in share mode;





可以看到两个客户端都可以查询出数据,不用阻塞等待;


2 分别 执行更新语句


update test_concurrence set name='namelock2111' where id='1';


update test_concurrence set name='namelock3333' where id='1';




检测到死锁,其中一个客户端更新失败,一个执行更新


3 分别执行  commit ,提交事务。


情景二

SELECT ... LOCK IN SHARE MODE: The rows read are the latest available, ** so if they belong to another transaction ** that has not yet committed, the read blocks until that transaction ends.


实验: 开启两个mysql 客户端


1  客户端1执行下面语句

begin;

 select * from test_concurrence where id='1' lock in share mode;

update test_concurrence set name='namelock2' where id='1';

 客户端2 执行


begin;

 select * from test_concurrence where id='1' lock in share mode;





可以看到客户端2 处于等待状态;


2 客户端1提交事务,执行“commit”;





客户端1事务提交成功,客户端3成功查询出数据。



答案


If there is another transaction, that has modified the row, the SELECT ... LOCK IN SHARE MODE waits. If the row is not modified, it does not wait. Which leads to the first situation, that 2 transaction can SELECT ... LOCK IN SHARE MODE, but none of them can update the record (deadlock)


如果有一个事务已经修改了记录数据,另一个事务执行“SELECT ... LOCK IN SHARE MODE ” 语句,则会等待;如果记录数据没有被修改,“SELECT ... LOCK IN SHARE MODE ” 不会等待,从而导致情景一,两个事务都可以成功执行“SELECT ... LOCK IN SHARE MODE”,但是会导致死锁。





参考链接:



http://stackoverflow.com/questions/6607006/select-lock-in-share-mode


http://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html

你可能感兴趣的:(JAVA)