簡體   English   中英

MySQLTransactionRollbackException:嘗試獲取鎖時發現死鎖;

[英]MySQLTransactionRollbackException: Deadlock found when trying to get lock;

我有一張表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

也許相同的兩個數據將同時由兩個線程處理,並且兩個線程都執行插入操作。

但是會導致死鎖嗎?我想知道為什么。

(mysql事務隔離級別是RR,InnoDB引擎)

這是一個古老的問題,但也許有人覺得它有用。

原因可能是MySQL的InnoDB使用插入意圖鎖,該意圖鎖在插入或更新時鎖定一組行。

檢查此鏈接以獲取有關InnoDB使用的不同類型的鎖的更多信息。

該鏈接解釋了一些有關死鎖的信息。

有時幾乎不可能避免這些僵局。 最常見的解決方案是:

  1. 第一個選項始終以相同的順序在表中運行
  2. 將交易范圍(持續時間)減少到最小
  3. 如有必要,請提前鎖定(已根據您的情況自動完成)
  4. 重試交易

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM