Seata 1.6.1 Global Lock Wait Timeout 问题分析与解决方案

在系统上线运行一段时间后,Seata Client 会出现拿不到全局锁的情况。

原因

常见的原因有并发更新,拿到全局锁的事务没有二次提交或者二次回滚,其它更新操作在重试时间范围内没拿到全局锁,会抛出此异常。

但是经过排查,报错服务获取的全局锁只有一个业务接口在用,首先排除这个常见问题。

经过 GitHub 查询,是由于全局事务的 timeout 设置过短,分支事务注册时,全局事务就回滚了,导致了锁泄露,属于 Bug。

缓解

  1. 避免过大的事务;
  2. Client 设置重试。
1
2
3
client.rm.lock.retryInterval=100
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=false

根治

  1. 设置合理的超时时间,并且保证 Client 和 Server 的时间是同步的;
  2. 升级到最新版本。
1
2
// 默认是60s
@GlobalTransactional(rollbackFor = Exception.class, timeoutMills = 100 * 1000)