1.重要说明
该问题出现的版本,seata
的 1.4.2
以下都会有。数据库:mysql
seata
执行undolog
时报错Cannot construct instance of java.time.LocalDateTime
,导致事务无法回滚异常!!!
这确实是一个比较严重的问题了!!!
seata
出现这个错,在github上面搜了issue一下,也是有比较多的人提了这个问题。详情可查看-->issue
基于上面的回答,有人提出,将序列化改成kryo
将 client.undo.logSerialization=kryo 序列化配置`nacos` ,然后重新启动seata服务
可问题是,哥们改了,也是不行呀,也是报转换异常。
然后又看到有人说:
字段换timestamp?然后序列化换成kryo 试试?
修改数据库表中的datetime类型为timestamp, client.undo.logSerialization=kryo 序列化配置至 nacos ,然后重新启动seata服务
这个是多么大的一个工程,而且线上的环境,这么操作,也有点问题。这很显示不适用于已上线的项目。
也有人说,可以升级版本。
但是我们对seata源码有进行改造,适配了一些国产化环境,贸贸然升级,好像也不是很好!!!
那哥们只能:阿巴阿巴阿巴!!!
基于以上的一些说法,哥们还是想研究看看,究竟是哪里导致这个异常的!!!
有兴趣的小伙伴,可以继续往下看!!!^_^
2.seata源码分析
seata版本:1.4.1
seata源码的构建,可以参考这里:点击查看,这里就不再一 一讲解了!!!
我们可以通过查看报错异常,快速定位到具体源码的位置。
异常方法栈:
打印日志源码:
可以看到JacksonUndoLogParser
类,对undolog的日志,进行json格式化处理。
然后我们查看一下,这1.4.1版本的seata,这个JacksonUndoLogParser
类。
可以看到,只有Timestamp
的序列化,是没有LocalDateTime
的序列化的。所以导致转换异常了。
然后,issue有人说到1.5.0版本,已经修复了这个bug!!!
那哥们去看一下这个JacksonUndoLogParser
类,做了什么修改,然后同步一下,不就好了嘛?
嗯嗯,有道理,真是个聪明的小可爱!!!
3.seata源码修改
1.5.0的seata的JacksonUndoLogParser
类
可以看到,他加了LocalDateTime
的序列化配置:
那我们同步一下这个修改,就好了!!!
具体的实现,就是上面的代码了。
1.5.0
版本的seata
的JacksonUndoLogParser
类,点击查看
然后,我们重新打包!!!
右键:pom.xml,选择Run Maven --> New Goal --> -Dmaven.test.skip=true -Dcheckstyle.skip=true clean install -U
打包成功后,是放在seata-distribution下面,直接就是和在官网下载的seata服务一样的文件
详细的可参考:查看这里
最后,测试一下,测试通过,完事!!!
好了,今天就先到这里了,溜了溜了溜了!!!^_^
觉得有收获的,帮忙点赞、评论、收藏
一下呗!!!
原文:https://juejin.cn/post/7103453026060337165