Seata Response[Could not found global transaction xid]
一、背景:
编程语言:java 业务框架:Spring全家桶
数据库:mysql 分布式事务框架:seata 1.4.2
二、场景描述:
原有项目的基础上集成分布式事务框架seata 1.4.2来进行分布式事务的管理。
seata没有集群,是单机的。seata只部署在一台云设备上。因为分布式需求没有那么大,目前只需要支持订单相关业务即可。
分布式事务主要是使用在订单支付上。
因为项目分布式化,现有两个模块:bussiness 和 pay。
业务订单逻辑在业务模块bussiness上,支付订单逻辑处理在支付模块pay上。
业务订单简要逻辑流程(createBusinessOrder):
- 参数校验和业务逻辑处理
- 创建业务订单(业务订单主键bussinessId)
- 远程调用创建支付订单方法(支付订单主键payId)
- 更新业务订单(主要将支付订单的payId更新到业务订单的payId字段上,形成关联)
- 其他逻辑处理
支付订单逻辑流程(createPayOrder):
- 逻辑处理
- 数据库中创建支付订单(就是简简单单地创建)
- 逻辑处理
- 返回
在业务订单方法(createBusinessOrder)上面添加AT模式下的全局事务注解
// 默认超时时间60秒 @GlobalTransactional(name = "business_order", rollbackFor = Exception.class)
feign调用重写apply方法,手动传递xid
@Override public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
template.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION));
}
String xid = RootContext.getXID();
if (StringUtils.isNotBlank(xid)) {
log.error("【分布式事务】feign获得分布式事务XID:{}", xid);
template.header(RootContext.KEY_XID, xid);
}
}
异常问题描述:
现在最大的问题是创建业务订单的时候,xid传递有时会丢失,没错是有时。
### Error updating database. Cause: java.sql.SQLException: io.seata.core.exception.RmTransactionException: Response[ TransactionException[Could not found global transaction xid = 192.168.0.123:8091:999975974789716363, may be has finished.] ]### The error may exist in com/demo/pay/dao/IOrderDao.java (best guess)
### The error may involve com.demo.pay.dao.IOrderDao.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO pay_order ( XXX,XXX,XXX, createUser, createTime, updateUser, updateTime ) VALUES ( ?, ?, ?, ?, ?, ?, ?)
### Cause: java.sql.SQLException: io.seata.core.exception.RmTransactionException: Response[ TransactionException[Could not found global transaction xid = 192.168.0.123:8091:999975974789716363, may be has finished.] ]
; uncategorized SQLException; SQL state [null]; error code [0]; io.seata.core.exception.RmTransactionException: Response[ TransactionException[Could not found global transaction xid = 192.168.0.123:8091:999975974789716363, may be has finished.] ]; nested exception is java.sql.SQLException: io.seata.core.exception.RmTransactionException: Response[ TransactionException[Could not found global transaction xid = 192.168.0.123:8091:999975974789716363, may be has finished.] ]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:89)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy167.insert(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
Caused by: io.seata.core.exception.RmTransactionException: Response[ TransactionException[Could not found global transaction xid = 192.168.0.123:8091:999975974789716363, may be has finished.] ]
at io.seata.rm.AbstractResourceManager.branchRegister(AbstractResourceManager.java:69)
at io.seata.rm.DefaultResourceManager.branchRegister(DefaultResourceManager.java:96)
at io.seata.rm.datasource.ConnectionProxy.register(ConnectionProxy.java:272)
at io.seata.rm.datasource.ConnectionProxy.processGlobalTransactionCommit(ConnectionProxy.java:250)
... 168 more
目前看了网上很多说法,说重试会导致xid找不到,超时找不到等等,针对网上的说法有做验证。
验证:
1.我们本地验证了全局事务不会对本地事务注解(@Transactional)有影响。
2.将feign调用改成不重试,但偶尔还是会出现,复现方式,在seata的部分源码的方法,打个断点,等3~5放开,之后出现xid找不到的问题几率大大上升。
3.超时,feign超时貌似没影响(我测试了几次没有出现过),全局事务超时,就不是这个了异常提示了,而是非常明确timeout异常,要回滚。
另外,今天也去看了seata-server的seata_gc.log日志发现gc的次数有点频繁,将seata-server重启,经过一个晚上的观察(前一天晚上21点多到今天早上9点多)查看日志,发现没有出现xid找不到的情况,但还在观察并不能说明问题解决。
最后,想求助用过seata的兄弟们,你们有遇到这种情况,这种问题。你们的解决思路,或者排查思路是什么样。
ps:想吐槽一下,seata貌似不是很稳定啊,不知道是不是我不会用的,或者用的方式不对。如果这个始终解决不掉,我们可能会换掉seata了,尝试其他的框架,或者走补偿机制。
回答:
同样seata1.4.2出现这个问题 也是单机部署 偶尔会出现这个问题 而且一出现就是一连串的-。- GitHub上的lssues都翻遍了好多这种问题
回答:
个例供参考
现象:1.4.2 版本突然出现该问题,之前运行一直正常
操作:
- 单纯的重启 seata 问题仍存在
- 排查发现几台服务器间时间不一致,重新同步时间之后,问题解决
以上是 Seata Response[Could not found global transaction xid] 的全部内容, 来源链接: utcz.com/p/944191.html