Could not commit JDBC transaction; nested exception is io.seata.rm.datasource.exec.LockWaitTimeoutException: Global lock wait timeout怎么意思?
获取全局锁失败,这个一般是资源竞争导致,请保证你竞争资源的周期是合理的,并且在业务上做好重试。 当一个全局事务因为获取锁失败的时候,应该重新完整地从@Globaltransational的tm端重新发起。——该回答整理自钉群“3群-Seata 开源讨论群”
这个问题其实就是全局锁等待超时问题,那么这里就需要明确两个概念:本地锁,全局锁,本地锁和全局锁都是只有一个。在多个业务请求进来时,如tx1、tx2等,会先争抢本地锁,抢到本地锁后修改数据,在要提交的时候会去获取全局锁,没有抢到本地锁的请求业务那么就会等待抢到本地锁并且获取到全局锁的业务提交完成释放本地锁了才能进行业务,那么这些就是阶段一的操作,那么阶段二就是全局事务的提交和回滚问题,这里分为两种情况,情况一:业务正常就会提交全局事务,这个好理解。情况二:业务出现异常,需要回滚,那么例如先执行的业务为tx1,当tx1执行到阶段1获取全局锁提交本地事务后,然后业务异常需要回滚准备进入阶段二时,由于tx1在阶段一时获取到全局锁后,本地事务已经提交,并且释放了本地锁,那么等待的其他业务如tx2这是就能获取到本地锁,并且开始执行阶段一,但是由于这个时候全局锁还在tx1业务上,而本地锁在tx2业务上,并且tx1在阶段二需要回滚的时候需要本地锁,tx2在阶段一提交的时候需要全局锁,那么这个时候就都会等待,但是出于阶段一的tx2等待全局锁的,是等不过处于阶段二tx1等待本地锁的,那么此时处于阶段一的tx1就会抛出io.seata.rm.datasource.exec.LockWaitTimeoutException: Global lock wait timeout这个异常!从而释放掉本地锁,那么处于阶段二的tx2那么就会获得全局锁从而实现业务数据的回滚,从而也保障了不会发生脏写的问题。具体的理论演示效果可以参考官方文档:https://seata.io/zh-cn/docs/overview/what-is-seata.html
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。