视频地址: https://www.bilibili.com/video/bv1zY411N7tB
最近在调试接口的时候遇到了MySQL死锁问题,我自己测试的时候一切都好好的,但在并发下,就死锁了
其实死锁问题,并没有一个类似“万金油”的解决办法,解铃还需系铃人,能做的只有写这个代码的人自己去解决
第一次出现死锁,想必你也会和我一样整个人都是懵的,不知道如何下手,等你看过下面的文章明白了死锁,就不会害怕了
死锁异常
2022-06-15 16:05:22.216 ERROR 38907 --- [ XNIO-1 task-4] c.i.c.exception.GlobalExceptionHandler :
### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may exist in file [/Users/xiaodaoxian/Desktop/work/code/ideamake-market-cloud-third-dock/target/classes/mapper/YxxWkBatchDataMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: DELETE FROM xdx_test_two WHERE user_id = ?
### Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
一、理论(重要)
所谓的死锁,一定是两个线程互相等待对方的资源。对于MySQL 来说,那就是两个事物
锁住了对方的数据。
MySQL的innodb有 表锁、行锁,如果锁表那死锁的概率很大,一般我们操作都是带有参数的 where user_id = 'xxx'
理论上如果写delete or update
的时候带了上面的条件,按照我们的理解那就是行锁,并发情况下只要我们参数不一致那永远不会造成死锁
但实际情况总不会如人意的,我造成死锁的2个SQL就是上面这样的操作,两个删除都是带了 where,但还是锁表了
MySQL InnoDB 引擎下,delete/update操作where后面的条件如果没有走索引,会锁表(MySQL 5.6/7 版本验证)
请注意上面我说的是 两个事物互相锁住了对方的资源
而并不是简单的两个SQL,这也就是为什么需要熟悉业务代码的人去解决,一个复杂的业务可能涉及到七八张