遇到一死锁现象:
事务级别中使用了最高的隔离级别:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
一个事件中,先select,如果没有则insert,有则update
当两个请求同事到达时,死锁发生了
下面详细描述一下:
CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
事务1 事务2
begin;
select * from t1 where a = 88; #select会自动加一把共享锁
Empty set (0.00 sec)
begin;
select * from t1 where a = 88; #几乎同一时间也加了一把共享锁
Empty set (0.00 sec)
insert into t1 values(88, 10000); #由于事务1加了共享锁,插入要等事务1提交
insert into t1 values(88, 10000);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
#因为发现没有记录存在,也执行插入
#但是由于事务2也加了一把共享锁,导致死锁
#当前事务被迫结束并rollback了
Query OK, 1 row affected (6.37 sec) #插入成功
事务级别中使用了最高的隔离级别:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
一个事件中,先select,如果没有则insert,有则update
当两个请求同事到达时,死锁发生了
下面详细描述一下:
CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
事务1 事务2
begin;
select * from t1 where a = 88; #select会自动加一把共享锁
Empty set (0.00 sec)
begin;
select * from t1 where a = 88; #几乎同一时间也加了一把共享锁
Empty set (0.00 sec)
insert into t1 values(88, 10000); #由于事务1加了共享锁,插入要等事务1提交
insert into t1 values(88, 10000);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
#因为发现没有记录存在,也执行插入
#但是由于事务2也加了一把共享锁,导致死锁
#当前事务被迫结束并rollback了
Query OK, 1 row affected (6.37 sec) #插入成功
这种情况就是由于事务的隔离级别为SERIALIZABLE,select语句会隐式地加上LOCK IN SHARE MODE,但是这并不影响select查询出结果,它只是不可以修改
本想在select语句上显示地加上FOR UPDATE互斥锁,强制让另一事件查询都阻塞,但是因为那条记录一开始就不存在,FOR UPDATE并不能起作用,两个事务仍然都可以select,并且均返回无记录
那如何解决这个问题呢? 有两种方法:
一种是事件隔离级别设置为非SERIALIZABLE,select这里都会成功,应用层两个事件中都会继续执行,这样子一个事务插入成功了
但是另一事务肯定会插入失败,但是由于上面select语句均返回无记录,但确在插入时出错了,调用失败了,调用端发现失败只能重新发送请求
另一种方法是,先不要select,先执行insert,然后根据结是否重复决定事务的后面处理流程,这样子一个事务插入成功,另一事务肯定会插入重复,重复后再执行修改
具体要根据业务特点决定使用适合的解决方法。
另外:大多数情况下不需要用到"SERIERLIZED"这个隔离级别,一般情况下"READ-COMMITTED"就可以满足要求了。
本文详细阐述了在使用最高隔离级别(SERIALIZABLE)时,事务间出现死锁的现象及其原因。通过具体示例展示了在尝试执行 select、insert 和 update 操作时,两个并发事务之间的死锁情况。文章进一步探讨了解决此类问题的两种方法:改变事务隔离级别以允许并发操作,或调整查询顺序以避免冲突。同时强调了在实际应用中合理选择事务隔离级别的重要性。
3678

被折叠的 条评论
为什么被折叠?



