【发布时间】:2016-08-11 13:29:08
【问题描述】:
我有一个表 trade_order:
CREATE TABLE `trade_order` IF NOT EXISTS `buyer_order` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`order_no` varchar(30) NOT NULL DEFAULT '',
`name` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `order_no` (`order_no`),
)
现在我想将数据插入到表 trade_order。我是这样做的:
transaction begin.
===
result = select * from order_table where order_no = #{orderNo} for update
if(result is null){
insert into trade_order (order_no,name) values (orderNo,name)
}
else{
update trade_order set name = #{name} where order_no = #{orderNo}
}
===
transaction end.
但我遇到了死锁异常:
org.springframework.dao.DeadlockLoserDataAccessException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may involve com.youzan.trade.process.datasync.dal.dao.OrderDAO.insert-Inline
### The error occurred while setting parameters
### SQL: insert into trade_order ( order_no, name ) values ( ?, ?, )
### 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; try restarting transaction
也许相同的两个数据会被两个线程同时处理,两个线程都做insert动作。
但是会导致死锁吗?不知道为什么。
(mysql事务隔离级别为RR,InnoDB引擎)
【问题讨论】:
-
查询和插入好像不在同一个事务中。我看到你正在使用一个 dao 框架。您确定所有操作都使用相同的事务吗?如果从查询中删除 for update?
-
你能用dev.mysql.com/doc/refman/5.7/en/innodb-deadlocks.html这里解释的方法之一检索更多关于死锁的信息吗?
-
这里有一个关于在简单插入期间出现意外死锁的有趣解释。问题似乎与具有自动增量的主键和像您的表一样的唯一 ley 的存在有关:dba.stackexchange.com/questions/86878/…
标签: java mysql multithreading