我有一个带有MySQL InnoDB表的系统,一个集群的Quartz调度程序和用于db层的MyBatis。
Quartz每隔30秒运行一次作业,检查数据库中的一些内容。直到最近,当我不得不为服务方法添加org.mybatis.guice.transactional.Transactional(isolation = Isolation.SERIALIZABLE,executorType = ExecutorType.BATCH)注释时,一切都运行正常,实际上甚至没有触及数据显然失败的触发器的工作会触及。
所以,现在发生的事情是,在使用该事务化服务方法一段时间后,它可能已经失败了对自己的并发调用(虽然在日志中没有任何关于这个),每30秒我得到一个在Quartz作业中出现死锁的日志中的异常,MySQL告诉我死锁是如下:
最新检测到的死锁
160226 12:20:00 *(1)TRANSACTION:TRANSACTION 28465C8,ACTIVE 0 sec启动索引读取mysql表中使用1,锁定1 LOCK WAIT 3锁定struct(s),堆 大小376,2行锁(s)MySQL线程ID 229934,OS线程句柄 0x7efcefcf7700,查询号76969784 server-node2 192.168.0.8 system-username排序结果SELECT TRIGGER_NAME,TRIGGER_GROUP, NEXT_FIRE_TIME,优先级来自QRTZ_TRIGGERS,其中SCHED_NAME = ' CloudScheduler'和TRIGGER_STATE ='等待' AND NEXT_FIRE_TIME< = 1456482030017 AND(MISFIRE_INSTR = -1 OR(MISFIRE_INSTR!= -1 AND NEXT_FIRE_TIME> = 1456481940018))按NEXT_FIRE_TIME ASC排序, 优先权DESC * (1)等待此锁定被授予:RECORD LOCKS空格id 0页面737 n位128索引
PRIMARY
表cloudsystem
。QRTZ_TRIGGERS
trx id 28465C8锁定模式S锁定rec但是 没有间隙等待记录锁,堆没有55物理记录:n_fields 18; 紧凑格式; info bits 0 0:len 19;十六进制 5468657265436c6f75645363686564756c6572; asc CloudScheduler ;; 1:len 29; hex 41646d696e5573657253657474696e7355706461746554726967676572; asc UserSettingsUpdateTrigger ;; 2:len 7; hex 44454641554c54; ASC 默认;; 3:len 6; hex 0000028465c2; asc e ;; 4:len 7;十六进制 20000004ca2763; asc' c ;; 5:len 23;十六进制 41646d696e5573657253657474696e6773557064617465; ASC UserSettingsUpdate ;; 6:len 17;十六进制 41646d696e5573657253657474696e6773; asc UserSettings ;; 7:SQL NULL; 8:len 8; hex 800001531d1811b0; asc S ;; 9:len 8;十六进制 800001531d179c80; asc S ;; 10:len 4; hex 80000005; asc ;; 11:len 8; hex 4143515549524544; asc获取;; 12:len 4;十六进制 43524f4e; asc CRON ;; 13:len 8; hex 80000153195c6d28; asc S \ m(;; 14:len 8;十六进制8000000000000000; asc ;; 15:SQL NULL; 16: len 2; hex 8000; asc ;; 17:len 0;十六进制asc ;;*(2)TRANSACTION:TRANSACTION 28465C2,ACTIVE 0秒更新或删除正在使用的mysql表1,锁定1 10个锁定结构,堆大小 1248,15行锁,撤消日志条目1 MySQL线程ID 230109,OS 线程句柄0x7efcef9e7700,查询ID 76969780 server-node1 192.168.0.7 system-username更新UPDATE QRTZ_TRIGGERS设置TRIGGER_STATE ='已获取' SCHED_NAME =' CloudScheduler'和 TRIGGER_NAME =' UserSettingsUpdateTrigger'和TRIGGER_GROUP = ' DEFAULT'和TRIGGER_STATE ='等待' * (2)HOLDS THE LOCK(S):RECORD LOCKS space id 0 page no 737 n bits 120 table
PRIMARY
的{{1}}索引。cloudsystem
trx id 28465C2 lock_mode X锁定rec而不是gap记录锁定,堆没有55 物理记录:n_fields 18;紧凑格式; info bits 0 0:len 19; hex 5468657265436c6f75645363686564756c6572; asc CloudScheduler ;; 1: len 29;十六进制 41646d696e5573657253657474696e7355706461746554726967676572; ASC UserSettingsUpdateTrigger ;; 2:len 7; hex 44454641554c54; ASC 默认;; 3:len 6; hex 0000028465c2; asc e ;; 4:len 7;十六进制 20000004ca2763; asc' c ;; 5:len 23;十六进制 41646d696e5573657253657474696e6773557064617465; ASC UserSettingsUpdate ;; 6:len 17;十六进制 41646d696e5573657253657474696e6773; asc UserSettings ;; 7:SQL NULL; 8:len 8; hex 800001531d1811b0; asc S ;; 9:len 8;十六进制 800001531d179c80; asc S ;; 10:len 4; hex 80000005; asc ;; 11:len 8; hex 4143515549524544; asc获取;; 12:len 4;十六进制 43524f4e; asc CRON ;; 13:len 8; hex 80000153195c6d28; asc S \ m(;; 14:len 8;十六进制8000000000000000; asc ;; 15:SQL NULL; 16: len 2; hex 8000; asc ;; 17:len 0;十六进制asc ;;***(2)等待此锁定被授予:记录锁空间id 0页没有759 n位120索引
QRTZ_TRIGGERS
的表IDX_QRTZ_T_NFT_ST
。cloudsystem
trx id 28465C2 lock_mode X锁定rec但是 没有间隙等待记录锁,堆没有51物理记录:n_fields 5; 紧凑格式; info bits 0 0:len 19;十六进制 5468657265436c6f75645363686564756c6572; asc CloudScheduler ;; 1:len 7; hex 57414954494e47; asc WAITING ;; 2:len 8; hex 800001531d1811b0; asc S ;; 3:len 29;十六进制 41646d696e5573657253657474696e7355706461746554726967676572; ASC UserSettingsUpdateTrigger ;; 4:len 7; hex 44454641554c54; ASC DEFAULT ;;***我们回滚交易(1)
所以这让我很奇怪。可序列化事务的实例可能在其他地方"失败了,但这不应该导致这种现象,这种现象每次都会反复发生。也不应该同时运行多个调度程序作业。
另一个问题是@Transactional注释似乎没有回滚事务 - 在这些死锁开始出现后,数据库中的数据已损坏。有趣的是,在交易不可序列化的应用程序的其他地方,异常的回滚可以正常工作。
MyBatis文档对这些问题并不十分冗长,但我还需要做些什么才能使我的交易安全地序列化
QRTZ_TRIGGERS
答案 0 :(得分:0)
这不是一个明确的答案,但同时也有太多的信息无法发表评论。
我想分享一些我的想法。
"实际上甚至没有触及的服务方法的注释 显然失败的触发器工作将触及的数据。"
干杯,