死锁产生前置条件:
1.互斥条件:一个资源只能被一个线程占有
2.请求与保持条件:一个线程请求资源阻塞,保持已有资源不释放
3.不剥夺条件:线程间不能强行剥夺
4.循环等待:多个线程形成首位相接的循环等待资源关系链
死锁处理方法:
1.查看死锁进程id,杀掉该进程(一种临时解决方案,总不能在生产环境上排查死锁、Kill sp,我们应该考虑如何去避免死锁)
查看mysql中,死锁线程:
2.设置锁超时时间
mysql:
# 查询全局等待事务锁超时时间 SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout'; # 设置全局等待事务锁超时时间 SET GLOBAL innodb_lock_wait_timeout=100; # 查询当前会话等待事务锁超时时间 SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';
超时后抛出CannotAcquireLockException等,可以对异常捕获,利用传播级别为requires_new,假设内层抛出,外层事务可以选择提交
最核心的是:避免死锁
打破死锁前置条件中的一条或多条,就可以避免死锁发生
(1).顺序访问对象,避免出现循环
(2).减少持有资源的时间(事务简短),减少锁竞争
(3).使用较低的隔离级别。(比如:读已提交)比使用较(可序列化)持有共享锁的时间更短,减少锁竞争)
tip:除这三种较为普通的,还有针对不同数据库层面的设置