背景:
有一张表须要天天定时迁移数据,采用的SQL以下(表名已调整)html
insert into data_cache ( customerID,organizationID,createTime) ( select customerID,organizationID,createTime from data where DATE(createTime) <= DATE(?) and autoIndex >= ? and autoIndex <= ? )
大致意思是根据autoIndex去断定那些数据须要迁移,在程序中已经分好区域了mysql
好比1~100,101~200,201~300.spring
表结构以下:sql
两张表的数据表结构均一致,如:数据库
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字段,取消自增以及非空。重试正常。spa
问题根源:
其实真正的问题涉及到Mysql对自增的设计。
详情能够参阅:
https://www.cnblogs.com/JiangLe/p/6362770.html
大致就是数据库的模式对这种自增插入有3种设置。原有的环境以及生产为2,更新后改成1致使的。
能够输入如下命令查看设置:
show global variables
innodb_autoinc_lock_mode 2
由于咱们对连续没什么要求,因此采用性能最好的便可