seata事务回滚问题全局锁死锁解决
seata事务回滚问题全局锁死锁问题seata时序图流程图
·
TM的本身也是一个RM
先上一个时序图
关于seata事务多次操作同一数据可能导致回滚异常的问题
分支事务回滚时 会根据全局事务xid到branch_table中按照记录生成的时间(gmt_create
) 正序查询所有分支事件记录放入List中,之后从List里倒序取出,挨个执行回滚! 然后惊奇的发现 每次出现上述回滚异常 都是因为 有两条或多条branch_table记录的 gm_create是相同的 以致于后续回滚查询分支事务的时候 无法保证其先后顺序,而后执行回滚的顺序 就一样无法保证.
如上:无法保证顺序.除非修改源码.否则应该尽量避免一个大事务多次操作同一个数据.并且是在同一秒内
还有一个事务回滚问题
在事务本地锁已经释放的时候.全局锁还存在.假设还有一个线程执行任务.是可以获取到本地锁的.也有可能导致回滚的异常.可以加入@GLOBALLOCK解决问题.
seata如何解决全局事务回滚的死锁问题
如果是同样的加了GlobalTransactional的事务.
事务1获取本地锁执行完获取全局锁后释放本地锁.(此时全局锁依然在)
事务2获取到相同本地锁执行完后去获取全局锁.此时全局锁没有释放
假设任务失败需要回滚
事务1发起全局回滚此时需要获取本地锁回滚
但是事务2持有了本地锁去获取全局锁.
此时死锁形成.这种情况seata的解决方案是.优先释放事务2的本地锁.让事务1的全局锁能去执行回滚操作.
seata的全局锁到底是什么?
seata的全局锁类似行锁.也是对于记录的锁.
存在lock_table中 pk就是数据主键.对这个记录会进行锁定
总结
seata的性能其实比较差.但是对于全局事务的实现比较方便.在不考虑大批量新增更新操作的情况下是个很好的解决方案,但是要避坑.
更多推荐
已为社区贡献1条内容
所有评论(0)