数据库死锁的问题不知道大家有没有见过,反正我干了三年多CRUD是第一次见。
接下来就一起来看看我遇到的这个死锁到底是怎样造成的?怎么解决的?
首先贴一下报错信息
- ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:
- Deadlock found when trying to get lock;
- try restarting transaction; SQL [];
- Deadlock found when trying to get lock;
- try restarting transaction;
- nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:
- Deadlock found when trying to get lock;
- 复制代码
当时的业务逻辑大概是这样的,如下图
现在给他简化一下
这就是典型的相互等待造成的死锁,一个持有锁,一直无法释放;一个等待锁,一直获取不到。
经过跟同事及leader的沟通,大概给出三种方案
针对上面造成死锁的问题,可以将RPC的调用另起一个线程去执行;主线程去执行数据更新的操作。
但是这种方式就是万无一失么,有什么问题呢?
把接口A中的事务进行细化拆分:
这个解决了响应无法返回的问题,但还是那个问题,如果RPC调用失败了,更新的数据无法回滚。
上述死锁问题的解决
另外,顺序处理也是能解决复杂一点的多事务的多表更新死锁问题的。
首先我们得保证两个或多个开启事务的接口,对数据库数据的处理尽量避免交叉更新,应该按顺序更新。
比如对多线程处理的第三个问题解决,如图
大伙们还有其他比较好的方案么,欢迎来沟通讨论啊。