Mysql自增列,並發插入時導致死鎖的問題


背景:

  有一張表需要每天定時遷移數據,采用的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種設置。原有的環境以及生產為2,更新后改為1導致的。

可以輸入以下命令查看設置:

show global variables

innodb_autoinc_lock_mode 2 

因為我們對連續沒什么要求,所以采用性能最好的即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM