我们在 WebSphere Liberty 上运行一个简单的 web 应用程序,它使用 Hibernate 作为持久性提供程序(作为库包含在 WAR 文件中)。
当应用程序启动时,Hibernate 被初始化,它将打开到 DB2 的连接并发出一些 SQL 语句。但是,当在 CICS 上运行并使用 JDBC Type 2 Driver DataSource 时,这会失败。记录以下消息(一些额外的换行符以提高可读性):
WARN org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator -
HHH000342: Could not obtain connection to query metadata : [jcc][50053][12310][4.19.56]
T2zOS exception: [jcc][T2zos]T2zosCicsApi.checkApiStatus:
Thread is not CICS-DB2 compatible: CICS_REGION_BUT_API_DISALLOWED ERRORCODE=-4228, SQLSTATE=null
...
ERROR org.hibernate.hql.spi.id.IdTableHelper - Unable obtain JDBC Connection
com.ibm.db2.jcc.am.SqlException: [jcc][50053][12310][4.19.56] T2zOS exception: [jcc][T2zos]T2zosCicsApi.checkApiStatus:
Thread is not CICS-DB2 compatible: CICS_REGION_BUT_API_DISALLOWED ERRORCODE=-4228, SQLSTATE=null
at com.ibm.db2.jcc.am.kd.a(Unknown Source) ~[db2jcc4.jar:?]
...
at com.ibm.db2.jcc.t2zos.T2zosConnection.a(Unknown Source) ~[db2jcc4.jar:?]
...
at com.ibm.db2.jcc.DB2SimpleDataSource.getConnection(Unknown Source) ~[db2jcc4.jar:?]
at com.ibm.cics.wlp.jdbc.internal.CICSDataSource.getConnection(CICSDataSource.java:176) ~[?:?]
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[our-app.war:5.1.0.Final]
at org.hibernate.internal.SessionFactoryImpl$3.obtainConnection(SessionFactoryImpl.java:643) ~[our-app.war:5.1.0.Final]
at org.hibernate.hql.spi.id.IdTableHelper.executeIdTableCreationStatements(IdTableHelper.java:67) [our-app.war:5.1.0.Final]
at org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:125) [our-app.war:5.1.0.Final]
at org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy.finishPreparation(GlobalTemporaryTableBulkIdStrategy.java:42) [our-app.war:5.1.0.Final]
at org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.prepare(AbstractMultiTableBulkIdStrategyImpl.java:88) [our-app.war:5.1.0.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:451) [our-app.war:5.1.0.Final]
我目前的理解是,当在 CICS 上运行并使用 JDBC Type 2 驱动程序时,只有一些线程能够打开 DB2 连接。那将是应用程序线程(处理 HTTP 请求的线程)以及服务于CICSExecutorService
.
目前的解决方案是:
JdbcEnvironmentInitiator
通过将hibernate.temp.use_jdbc_metadata_defaults
属性设置为 禁用 JDBC 元数据查找false
- 将执行包装
IdTableHelper#executeIdTableCreationStatements
在 a 中Runnable
并将其提交给CICSExecutorService
.
您认为此解决方案是否足够且适合生产?或者,也许你使用一些不同的方法?
使用的版本:
- 适用于 z/OS 5.3.0 的 CICS 事务服务器
- WebSphere 应用服务器 8.5.5.8
- 休眠 5.1.0
更新:澄清一下,一旦我们的应用程序启动,它就可以毫无问题地查询 DB2(在服务 HTTP 请求时)。该问题仅与启动有关。