seata 1.4.3版本在mysql8.0中执行undo时报错Cannot construct instance of `java.time.LocalDateTime`的原因及解决方法
seata 1.3客户端事务参与者在执行事务回滚时,出现了如下的异常错误信息:
2021-12-30 15:18:28.337 ERROR 4468 --- [h_RMROLE_1_4_16] i.s.r.d.u.parser.JacksonUndoLogParser : json decode exception, Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"{"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"10.18.0.50:8091:8683154678292422717","branchId":8683154678292422718,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"INSERT","tableName":"p_order","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords","tableName":"p_order","rows":["java.util.ArrayList",[]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"p_order""[truncated 1547 bytes]; line: 1, column: 1410] (through reference chain: io.seata.rm.datasource.undo.BranchUndoLog["sqlUndoLogs"]->java.util.ArrayList[0]->io.seata.rm.datasource.undo.SQLUndoLog["afterImage"]->io.seata.rm.datasource.sql.struct.TableRecords["rows"]->java.util.ArrayList[0]->io.seata.rm.datasource.sql.struct.Row["fields"]->java.util.ArrayList[6]->io.seata.rm.datasource.sql.struct.Field["value"])
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (byte[])"{"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"10.18.0.50:8091:8683154678292422717","branchId":8683154678292422718,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"INSERT","tableName":"p_order","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords$EmptyTableRecords","tableName":"p_order","rows":["java.util.ArrayList",[]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"p_order""[truncated 1547 bytes]; line: 1, column: 1410] (through reference chain: io.seata.rm.datasource.undo.BranchUndoLog["sqlUndoLogs"]->java.util.ArrayList[0]->io.seata.rm.datasource.undo.SQLUndoLog["afterImage"]->io.seata.rm.datasource.sql.struct.TableRecords["rows"]->java.util.ArrayList[0]->io.seata.rm.datasource.sql.struct.Row["fields"]->java.util.ArrayList[6]->io.seata.rm.datasource.sql.struct.Field["value"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.11.4.jar:2.11.4]
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1615) ~[jackson-databind-2.11.4.jar:2.11.4]
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400) ~[jackson-databind-2.11.4.jar:2.11.4]
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1077) ~[jackson-databind-2.11.4.jar:2.11.4]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1332) ~[jackson-databind-2.11.4.jar:2.11.4]
现象原因,日期时间类型设置为datetime:

解决方法:

修改数据库表undo_log中的datetime类型为timestamp,此方法不适用于已上线的项目,新项目可采用该方法临时解决,等新版本seata发布以后再改回来。
需要做回滚的业务表的datetime类型也修改为timestamp,不然执行回滚时反序列化会出现错误。
博客内容讲述了在使用 Seata 1.4.3 版本时,遇到在 MySQL 8.0 数据库中执行事务回滚操作报错 `Cannot construct instance of java.time.LocalDateTime` 的问题。原因是 LocalDateTime 类型无法被正确反序列化。解决方案是将数据库表中的 datetime 类型改为 timestamp,同时需要同步更新业务表的 datetime 类型,以避免回滚时的反序列化错误。但此方法不适用于已上线项目。建议关注 Seata 新版本更新以获取更佳解决方案。

1277

被折叠的 条评论
为什么被折叠?



