Seata使用中遇到的问题汇总
一 Coul;d not commit JDBC transaction; nested exception is io.seata.rm.datasource.exec.LockConflictException:get global lock fail
获取全局锁失败;
顺序解决方案:
1.查看当前seata-server端连接的数据库中的对应表 lock_table 中的row_key长度
2021-01-14 16:38:28.243 ERROR --- [ ServerHandlerThread_1_19_500] i.s.s.s.db.lock.LockStoreDataBaseDAO : Global lock batch acquire error: Data truncation: Data too long for column 'row_key' at row 1
==>
java.sql.BatchUpdateException: Data truncation: Data too long for column 'row_key' at row 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.cj.util.Util.handleNewInstance(Util.java:192)
at com.mysql.cj.util.Util.getInstance(Util.java:167)
at com.mysql.cj.util.Util.getInstance(Util.java:174)
原因:
row_key的生成策略如下
protected List<LockDO> convertToLockDO(List<RowLock> locks) {
List<LockDO> lockDOs = new ArrayList<>();
if (CollectionUtils.isEmpty(locks)) {
return lockDOs;
}
for (RowLock rowLock : locks) {
LockDO lockDO = new LockDO();
lockDO.setBranchId(rowLock.getBranchId());
lockDO.setPk(rowLock.getPk());
lockDO.setResourceId(rowLock.getResourceId());
lockDO.setRowKey(getRowKey(rowLock.getResourceId(), rowLock.getTableName(), rowLock.getPk()));
lockDO.setXid(rowLock.getXid());
lockDO.setTransactionId(rowLock.getTransactionId());
lockDO.setTableName(rowLock.getTableName());
lockDOs.add(lockDO);
}
return lockDOs;
}
生成环境使用连接比较长,再拼接上 表名 + 主键 所以出现了 row_key 超长的情况。
2.因为引入了seata框架,再加上最后的异常信息也指向了seata,群友讨论怀疑是竞争锁导致的。所以修改seata服务的参数
client.rm.lock.retryInterval 20 校验或占用全局锁重试间隔 默认10,单位毫秒
client.rm.lock.retryTimes 60 校验或占用全局锁重试次数 默认30
浙公网安备 33010602011771号