【问题标题】:Hibernate connecting to DB2 at application startup on WAS Liberty on CICS在 CICS 上的 WAS Liberty 上的应用程序启动时休眠连接到 DB2
【发布时间】:2016-09-14 11:17:32
【问题描述】:

我们正在 WebSphere Liberty 上运行一个简单的 Web 应用程序,它使用 Hibernate 作为持久性提供程序(作为库包含在 WAR 文件中)。

当应用程序启动时,Hibernate 被初始化,它将打开一个到 DB2 的连接并发出一些 SQL 语句。但是,当在 CICS 上运行并使用 JDBC 类型 2 驱动程序数据源时,这会失败。记录了以下消息(一些额外的换行符以提高可读性):

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 的工作线程。

目前的解决方案是:

  1. JdbcEnvironmentInitiator 中禁用 JDBC 元数据查找 将hibernate.temp.use_jdbc_metadata_defaults 属性设置为 false
  2. IdTableHelper#executeIdTableCreationStatements 的执行包装在Runnable 中并将其提交给CICSExecutorService

您认为此解决方案是否足够且适合生产?或者也许你使用了一些不同的方法?

使用的版本:

  • 用于 z/OS 5.3.0 的 CICS 事务服务器
  • WebSphere 应用服务器 8.5.5.8
  • 休眠 5.1.0

更新:澄清一下,一旦我们的应用程序启动,它就可以毫无问题地查询 DB2(在处理 HTTP 请求时)。该问题仅与启动有关。

【问题讨论】:

  • @Gas 你能说得更具体点吗?我只是仔细检查了——我们的 DB2 DataSource 配置与给定文章中的完全相同(没有指定 properties.db2.jcc)。
  • 但是 CICS 端配置了吗?在该页面上,您有配置CICS region 的链接。我不是 CICS 专家,因此无法帮助您。
  • @Gas 谢谢。 CICS 端已配置(不能说是否正确完成),但一般而言,一旦启动 webapp,DB2 访问就可以正常工作,只有在启动期间才会出现此问题。更新了帖子以澄清这一点。

标签: java db2 websphere-liberty cics db2-zos


【解决方案1】:

最近在服务刷新(2016 年 7 月)中提供了对 Liberty 中 JPA 功能的 CICS TS v5.3 支持。在该更新之前,尝试在应用程序中运行 JPA 会导致与您描述的问题非常相似的问题。

虽然您正在运行休眠并且您在启用 CICS 的线程上,但它没有 API 环境(这将允许类型 2 JDBC 调用成功)。新的检测逻辑是专门(但不是专门)为与 DB2 JDBC 2 类驱动程序和 JPA 一起使用而开发的。此更新是在最近的服务更新中发布的,可能会解决您遇到的问题。

尝试申请: http://www-01.ibm.com/support/docview.wss?crawler=1&uid=swg1PI58375

描述说它是为了支持“标准模式 Liberty”,但它包含上述其他开发。

【讨论】:

    【解决方案2】:

    以下解决方案经测试可以正常工作。

    这个想法是使用CICSExecutorService#runAsCICS 执行 SQL/DDL 语句。以下扩展是通过hibernate.hql.bulk_id_strategy 属性注册的。

    package org.hibernate.hql.spi.id.global;
    
    import java.util.concurrent.*;
    import org.hibernate.boot.spi.MetadataImplementor;
    import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
    import org.hibernate.engine.jdbc.spi.JdbcServices;
    import org.springframework.util.ClassUtils;
    import com.ibm.cics.server.*;
    
    public class CicsAwareGlobalTemporaryTableBulkIdStrategy extends GlobalTemporaryTableBulkIdStrategy {
    
        @Override
        protected void finishPreparation(JdbcServices jdbcServices, JdbcConnectionAccess connectionAccess, MetadataImplementor metadata, PreparationContextImpl context) {
            execute(() -> super.finishPreparation(jdbcServices, connectionAccess, metadata, context));
        }
    
        @Override
        public void release(JdbcServices jdbcServices, JdbcConnectionAccess connectionAccess) {
            execute(() -> super.release(jdbcServices, connectionAccess));
        }
    
        private void execute(Runnable runnable) {
            if (isCics() && IsCICS.getApiStatus() == IsCICS.CICS_REGION_BUT_API_DISALLOWED) {
                RunnableFuture<Void> task = new FutureTask<>(runnable, null);
                CICSExecutorService.runAsCICS(task);
                try {
                    task.get();
                } catch (InterruptedException | ExecutionException e) {
                    throw new RuntimeException("Failed to execute in a CICS API-enabled thread. " + e.getMessage(), e);
                }
            } else {
                runnable.run();
            }
        }
    
        private boolean isCics() {
            return ClassUtils.isPresent("com.ibm.cics.server.CICSExecutorService", null);
        }
    }
    

    请注意,较新的 JCICS API 版本对接受 CallablerunAsCics 方法有一个覆盖,这可能有助于将 execute 方法的 CICS 分支简化为如下所示:

    CICSExecutorService.runAsCICS(() -> { runnable.run(); return null; }).get();
    

    尝试了一些替代方案:

    1. 仅包装连接获取操作 (org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl#getConnection) 不起作用,因为在主线程中使用连接时已经关闭。
    2. 包装整个应用程序启动 (org.springframework.web.context.ContextLoaderListener#contextInitialized) 导致类加载问题。

    编辑:最终使用了自定义 Hibernate 的 MultiTableBulkIdStrategy 实现,它在启动时不运行任何 SQL/DDL (see project page on GitHub)。

    【讨论】:

      猜你喜欢
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 2017-07-05
      • 1970-01-01
      相关资源
      最近更新 更多