InnoDB数据库死锁问题的处理
的deadlockloserdataaccessexception例外出现在更新表的时间(死锁发现当试图获得锁;尝试重新启动交易)。
问题分析
这个例外,不影响用户的使用,因为数据库自动回滚和重试数据库时遇到了一个僵局。用户的感觉是操作一个小卡顿。但监测一直是异常的,因此它需要解决的问题。
解决方法
在应用程序中使用更新时,尝试使用catch。
我自己封装了一个函数,如下所示。
* 2016-03-15
*林
*在更新表时处理死锁
* /
private void updatewithdeadlock(testmapper制图、试验记录)抛出InterruptedException {
布尔啊;
int重试次数= 5;
做{
哎呀= false;
尝试{
mapper.updatebyprimarykeyselective(记录);
}
抓住(deadlockloserdataaccessexception dlex){
哎呀,真的;
Thread.sleep((长)(Math.random)*(500));
}
最后{
}
(啊= =真}而重试——> 0);
}
我使用MyBatis,所以只是把映射到功能,如果不是MyBatis,你需要创建和关闭数据库连接。
扩展:数据库死锁
数据库死锁中经常遇到的事务型数据库如SQL Server,MySQL的问题,等等。一般来说,数据库死锁问题并不严重,除非数据库死锁问题经常导致用户无法operate.try-catch可以在应用程序中完成的。因此数据死锁的形成
InnoDB实现行级锁,它分为共享锁(S)和互斥锁(X)。
共享锁用于事务读取行。
互斥体用于事务更新或删除行。
当客户A持有共享锁并请求互斥x时;同时,客户B持有互斥x并请求共享锁s。在上述情况下,数据库死锁将发生。
数据库死锁的例子
首先,客户A创建一个表T并插入一段数据到T中,而客户机A启动一个选择事务,因此它保存共享锁。
MySQL >创建表T(I型)= InnoDB引擎;
查询OK,0行受影响(1.07秒)
插入到t(i)值(1);
查询OK,1行受影响(0.09秒)
开始事务;
查询OK,0行受影响(0秒)
从t = i 1锁定共享模式;
------ + +
我| |
------ + +
1 | |
------ + +
然后,客户B启动一个新事务,新事务是删除表T中的唯一数据。
开始事务;
查询OK,0行受影响(0秒)
从t删除i = 1;
删除操作需要x,但是互斥x和共享锁s是不兼容的。因此,删除事务放在锁请求队列中,客户B被阻塞。
最后,客户A也希望删除表T中的数据:
从t删除i = 1;
错误1213(40001):在试图获取锁时发现死锁;
尝试重新启动交易
僵局即将来临!由于客户A需要锁定X删除行,客户B持有锁X,并正在等待客户A释放锁:
客户A:锁住锁,等待客户B释放锁X。
客户B:持有锁X,等待客户A释放锁s。
生死锁后,InnoDB会产生一个客户的错误信息和释放锁。返回到客户信息:
错误1213(40001):在试图获取锁时发现死锁;
尝试重新启动交易
因此,另一个客户可以正常执行任务。