欢迎使用普元产品知识库,本知识库包含普元应用开发平台EOSPlatform,流程平台BPS,企业服务总线ESB,微服务平台Microservice,运维管理平台Devops,数据集成平台DI
欢迎使用普元文档库
问题描述:某项目从eos6.7升级至eos7.6.6后,报错"You can't operate on a closed Connection!!!"的异常
at com.primeton.das.entity.impl.hibernate.persister.entity.AbstractEntityPersister.handlerSQLKeyword(AbstractEntityPersister.java:1020) [ptp-server-das-5.2.0.0.jar:5.2.0.0]
解答:
分析:在做业务实体查询等操作的时候,用到了hibernate框架,中间增加了对关键字的处理,要查询数据库的类型和版本号,这时候用到数据库连接,而数据库连接是缓存到DASSessionImpl.DataBaseConnection.connection全局静态变量中的,如下所示:
public static class DataBaseConnection{
private static Connection connection;
public static Connection getConnection() {
return connection;
}
}
因为是全局静态变量,所以JVM中只有一份,当多线程并发时,这个connection会被其他的线程改写,多数据源情况会造成connection发生被改写,从而引发线程不安全问题。
解决办法:
使用线程上下文来解决,修改代码如下:
public static class DataBaseConnection{
private static ThreadLocal<Connection> connHolder=new ThreadLocal<Connection>();
public static void setConnection(Connection conn) { //PLATFORM766多数据源情况下,实体查询等操作是在处理SQLKeyword偶发出现You can't operate on a closed Connection异常
connHolder.set(conn);;
}
public static Connection getConnection() {
return connHolder.get();
}
}
DASSessionImpl在初始化的时候,调用下面的:
public DASSessionImpl(Connection conn) {
this.conn = conn;
DASSessionImpl.DataBaseConnection.setConnection(conn);
this.s = SessionFactoryManager.INSTANCE.getFactory(conn).openSession(
conn);
}
总结:此问题已解决,可在ame发起小补丁申请补丁:PLATFORM_7.6.6_SERVER_20230221_P1