Mysql自增列,併發插入時導致死鎖的問題
阿新 • • 發佈:2018-12-16
背景:
有一張表需要每天定時遷移資料,採用的SQL如下(表名已調整)
insert into data_cache ( customerID,organizationID,createTime) ( select customerID,organizationID,createTime from data where DATE(createTime) <= DATE(?)and autoIndex >= ? and autoIndex <= ? )
大體意思是根據autoIndex去判定那些資料需要遷移,在程式中已經分好區域了
比如1~100,101~200,201~300.
表結構如下:
兩張表的資料表結構均一致,如:
CREATE TABLE `data` ( `customerID` varchar(50) NOT NULL COMMENT '客戶編號', `organizationID` varchar(50) DEFAULT NULL COMMENT '機構號', `createTime` timestamp NULL DEFAULT current_timestamp() COMMENT '建立時間', `lastModifiedDatetime` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '最近修改時間', `autoIndex` int(11) NOT NULL AUTO_INCREMENT COMMENT '索引', `modifyDate` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() COMMENT '修改日期', PRIMARY KEY (`customerID`), KEY `autoIndex` (`autoIndex`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=468 DEFAULT CHARSET=utf8
之前測試環境,甚至生產環境都是正常的程式碼,最近更新了資料庫,出現了死鎖異常如下:
insert into data_cache ( customerID,organizationID,createTime)
(
select customerID,organizationID,createTime
from data
where DATE(createTime) <= DATE(?)
and autoIndex >= ?
and autoIndex <= ?
)
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
org.springframework.dao.DeadlockLoserDataAccessException: PreparedStatementCallback;
問題:
Mysql插入居然報了死鎖,還是兩條插入併發,在資料來源沒有交集的情況下,並且之前一直是正常。百思不得其解
嘗試解決:
移除掉快取表中的autoIndex欄位,取消自增以及非空。重試正常。
問題根源:
其實真正的問題涉及到Mysql對自增的設計。
詳情可以參閱:
https://www.cnblogs.com/JiangLe/p/6362770.html
大體就是資料庫的模式對這種自增插入有3種設定。原有的環境以及生產為第二種,更新後改為第一種導致的。