最近一个模块执行时数据库老死锁,导致部分用户的数据没有更新。
发生死锁的方法在模块处理的最后数据更新部分,数据库操作如下:
死锁发生在updateGroupScore的时候。导致winAward(),loserAward()也回滚。
用户部分发生争锁的情况可能性要低。锁应该是两个事务对更新组时发生。发生的相互持有对方的锁且又等待对方释放锁时发生的。以简单的两个事务为例:
此时死锁就发生了。
何况这样操作的事务有很多,多个事务间相互等锁的几率就更大了。
目前想到方法:
[list]
[*]1. 在这个方法中加了个锁.
[*]2. 将winner, loser的处理分开,分成两个事务处理。这样在updateGroupScore就不会等锁
[*]3. 将updateGroupScore抽出, 想另外的方式进行更新。
[/list]
发生死锁的方法在模块处理的最后数据更新部分,数据库操作如下:
updateScore{
winuser = getUserById(winId); //for update形式
//设置winuser
update winuser
winAward(winuser); //奖励
updateGroupScore(winuser.getGroup())
loseruser = getUserById(loserId); //for update形式
//设置loseruser
Update(loseruser)
loserAward(loseruser)
updateGroupScore(loseruser.getGroup());
}
死锁发生在updateGroupScore的时候。导致winAward(),loserAward()也回滚。
用户部分发生争锁的情况可能性要低。锁应该是两个事务对更新组时发生。发生的相互持有对方的锁且又等待对方释放锁时发生的。以简单的两个事务为例:
Transaction1: tranaction2:
updateGroupScore 5 //锁住 group 5
updateGroupScore 2 //锁住 group 2
updateGroupScore 2 //waiting lock 2
updateGroupScore 5 //waiting lock 5
此时死锁就发生了。
何况这样操作的事务有很多,多个事务间相互等锁的几率就更大了。
目前想到方法:
[list]
[*]1. 在这个方法中加了个锁.
[*]2. 将winner, loser的处理分开,分成两个事务处理。这样在updateGroupScore就不会等锁
[*]3. 将updateGroupScore抽出, 想另外的方式进行更新。
[/list]