返回

利用全新的序列化策略,让 Seata 的 TCC 模式从此不再反序列化异常

后端

前言

在之前的文章中,我分享了在使用 Seata TCC 模式时发现的一个 BUG,并在 Seata 社区中提交了一个 issue。在实际集成 TCC 的过程中,我又发现了另一个问题:BusinessActionContext 的序列化方式存在缺陷,导致在反序列化时出现类型不一致的异常。

这个问题的根源在于 Seata 默认使用 Java 的内置序列化机制对 BusinessActionContext 进行序列化,而这种序列化方式无法保证不同版本的 Seata 客户端之间能够正确地反序列化对象。当 Seata 服务端和客户端使用不同版本的 Seata 时,就可能出现反序列化异常,导致分布式事务无法正常执行。

为了解决这个问题,我决定替换 Seata 的默认序列化方式,使用一种更加可靠和稳定的序列化策略。经过一番研究和实践,我最终选择了 Kryo 作为新的序列化框架。Kryo 是一个高性能的序列化库,具有速度快、体积小、跨语言支持等优点。

替换序列化方式的步骤

替换 Seata 的默认序列化方式需要以下几个步骤:

  1. 在 Seata 客户端和服务端添加 Kryo 依赖。
  2. 实现一个自定义的 KryoSerializer,并注册到 Seata 中。
  3. 在 Seata 配置文件中配置自定义的 KryoSerializer。

1. 添加 Kryo 依赖

在 Seata 客户端和服务端项目中,添加 Kryo 的依赖。可以使用以下 Maven 依赖:

<dependency>
    <groupId>com.esotericsoftware.kryo</groupId>
    <artifactId>kryo</artifactId>
    <version>5.2.0</version>
</dependency>

2. 实现自定义的 KryoSerializer

接下来,需要实现一个自定义的 KryoSerializer,并注册到 Seata 中。自定义的 KryoSerializer 需要继承 Seata 提供的 org.apache.seata.serializer.kryo.KryoSerializer 类,并重写 serializedeserialize 方法。

public class CustomKryoSerializer extends KryoSerializer {

    @Override
    protected void serialize(Kryo kryo, Output output, Object object) {
        kryo.writeClassAndObject(output, object);
    }

    @Override
    protected Object deserialize(Kryo kryo, Input input) {
        return kryo.readClassAndObject(input);
    }
}

3. 配置自定义的 KryoSerializer

最后,需要在 Seata 配置文件中配置自定义的 KryoSerializer。可以在 Seata 的 application.properties 文件中添加以下配置:

seata.serializer=com.example.CustomKryoSerializer

这样,就完成了 Seata 序列化方式的替换。

示例代码

为了更好地理解如何替换 Seata 的默认序列化方式,我提供了一个示例代码项目。该项目包含了一个 Seata 服务端和一个 Seata 客户端,以及一个简单的分布式事务示例。

在该项目中,我使用 Kryo 替换了 Seata 的默认序列化方式。通过运行该项目,可以验证 Seata TCC 模式的反序列化异常问题已经得到解决。

您可以通过以下链接下载示例代码项目:

示例代码项目下载链接

结论

通过替换 Seata 的默认序列化方式,我们可以从根源上解决反序列化类型不一致的问题,确保分布式事务的稳定性和可靠性。本文分享了详细的步骤和示例代码,帮助读者轻松实现 Seata TCC 模式的集成和使用。

希望本文能够对大家有所帮助。如果您有任何问题或建议,欢迎在评论区留言。