dtm
dtm copied to clipboard
INSERT IGNORE INTO barrier死锁问题
业务使用二阶段消息,发现报警: 1、GET /api/dtm/msg/queryPrepared?branch_id=00&gid=ZLk5US5qQF5tMGyEvCz4Kh&op=msg&trans_type=msg 响应状态码:500
2、死锁
SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction (SQL: INSERT IGNORE INTO barrier (trans_type, gid, branch_id, op, barrier_id, reason) values(msg,ZLk5US5qQF5tMGyEvCz4Kh,00,msg,01,rollback))
麻烦问下,出现这个的原因是什么?需要如何解决?
您是什么情况下发生这个问题呢?复现条件是? 我遇见的情况一般是你的本地业务持续很久没有完成导致的,导致回查拿不到锁,导致这个报错
1、业务逻辑如下 A用户进行操作,操作成功之后,会通过另一个接口进行消息通知 目前发现是操作失败,本地事务回滚了
DTM的2个表数据如下图


2、如何复现
就是让本地事务失败(可能是要有并发的情况),可能就可以复现了;

3、如何解决? 这种死锁,需要关注并解决吗?还是DTM会自动重试并解决?
你这说的复现条件不太具体,无法根据你的信息复现问题哈 有一种方式可以复现你的问题,就是返回前睡眠一分钟 这种情况通常是你的业务有故障了才会出现,虽然dtm会再次重试,最终一致,只是大家的业务,如果没有出现数据库故障,基本不会出现你的这个情况,因此建议你找出发生的原因
业务使用二阶段消息,发现报警: 1、GET /api/dtm/msg/queryPrepared?branch_id=00&gid=ZLk5US5qQF5tMGyEvCz4Kh&op=msg&trans_type=msg 响应状态码:500
2、死锁 SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction (SQL: INSERT IGNORE INTO
barrier(trans_type, gid, branch_id, op, barrier_id, reason) values(msg,ZLk5US5qQF5tMGyEvCz4Kh,00,msg,01,rollback))麻烦问下,出现这个的原因是什么?需要如何解决?
死锁语句是在插入 reason 为 rollback的时候,reason 为 rollback 的屏障插入通常在 /api/dtm/msg/queryPrepared 或者 /api/dtm/msg/queryPreparedB 。
如果是使用官方提供的 /api/dtm/msg/queryPreparedB 的话通常不会出现死锁,因为在 /api/dtm/msg/queryPreparedB接口中不需要操作业务表,也就没有循环等待。
只有在 自定义的/api/dtm/msg/queryPrepared 接口中,先访问了业务表,后又操作了屏障表,才会造成循环等待 死锁。
循环等待例子:
DoAndSubmitDB 会先操作屏障,然后处理业务
/api/dtm/msg/queryPrepared 先处理业务,在操作屏障
你可以排查一下。