在分布式部署环境中,Tomcat 的会话复制功能是实现高可用性的关键技术之一。但在实际应用中,可能会遇到与特定数据库驱动不兼容的问题。

问题现象
某系统采用 Tomcat 集群并启用了会话复制功能,运行过程中出现以下异常:

text
java.io.NotSerializableException: oracle.jdbc.driver.T4CConnection
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)

异常提示 Oracle 数据库驱动中的 T4CConnection 类无法被序列化,导致会话复制失败。

排查过程
首先检查应用程序代码,确认没有将 T4CConnection 或 java.sql.Connection 等数据库连接对象存入会话(Session)中。经过代码审查,确实不存在此类操作。

随后团队尝试了多种解决方案:

更换 Tomcat 版本

调整 Tomcat 集群配置参数

检查网络和防火墙设置

但上述尝试均未能解决问题。

根本原因分析
经过逐项排查和对比测试,最终定位到问题根源:应用中有个未实际使用的 java.sql.Clob 类型字段被存储在会话对象中。当 Tomcat
尝试序列化该会话以进行集群间复制时,Clob 字段引用的 Oracle 驱动内部对象无法正常序列化。

有趣的是,Tomcat 的错误提示并未明确指出 Clob 类型的问题,而是报告了其底层依赖的 Oracle 连接对象序列化失败,这在一定程度上误导了排查方向。

解决方案
由于该 Clob 字段在业务逻辑中并未实际使用,最终解决方案是移除该字段。修改后,会话复制功能恢复正常。

经验总结:

存储在会话中的对象必须实现 Serializable 接口

避免将数据库特定类型(如 Clob、Blob)直接存入会话

错误信息可能指向间接依赖对象,需要深入分析调用链