2016-09-14 12 views
2

우리는 Hibernate를 WAR 파일의 라이브러리로 포함 된 지속성 제공자로 사용하는 WebSphere Liberty에서 간단한 웹 애플리케이션을 실행 중이다.CICS의 WAS 리버티에서 애플리케이션 시작시 Hibernate에 연결

응용 프로그램이 시작될 때 최대 절전 모드가 초기화되고 DB2에 대한 연결이 열리고 일부 SQL 문이 실행됩니다. 그러나 CICS에서 실행 중이고 JDBC 유형 2 드라이 v 데이터 소스를 사용할 때 실패합니다. 다음과 같은 메시지가 (몇 가지 여분의 줄을 읽기 쉽도록 나누기) 기록됩니다

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 유형을 사용하는 경우이 드라이버는 일부 스레드가 DB2 연결을 열 수 있다는 것입니다. 이는 응용 프로그램 스레드 (HTTP 요청을 처리하는 스레드)와 CICSExecutorService을 처리하는 작업자 스레드가됩니다. 가 RunnableIdTableHelper#executeIdTableCreationStatementsfalse

  • 랩 실행될 hibernate.temp.use_jdbc_metadata_defaults 속성을 설정하고 CICSExecutorService에 제출하여 JdbcEnvironmentInitiator

    1. 안 JDBC 메타 데이터 검색 :

      현재의 솔루션이다.

    이 솔루션이 생산에 적합하고 적절하다고 생각하십니까? 아니면 다른 접근 방식을 사용하고 있을까요? 사용

    버전 : Z에 대한

    • CICS 트랜잭션 서버/OS 5.3.0
    • WebSphere Application Server에 8.5.5.8
    • 최대 절전 모드 5.1.0

    업데이트 : 일단 애플리케이션이 시작된 후에는 DB2를 아무런 문제없이 쿼리 할 수 ​​있습니다. (HTTP 요청을 처리 할 때). 문제는 시작과 관련이 있습니다.

  • +1

    [Liberty 용 CICS DB2 JDBC 유형 2 드라이버 데이터 소스 수동 구성] (https://www.ibm.com/support/knowledgecenter/SSGMCP_5.3.0/com.ibm.cics.ts.java.doc)을 점검하십시오. /topics/config_db2datasource_liberty.html) – Gas

    +0

    @Gas 좀 더 구체적으로 말씀해 주시겠습니까? 방금 두 번 확인했습니다. DB2 DataSource 구성은 given article과 정확히 동일합니다 (properties.db2.jcc가 지정되지 않은 경우). –

    +0

    그러나 CICS 측이 구성 되었습니까? 해당 페이지에서 [CICS region] (https://www.ibm.com/support/knowledgecenter/SSGMCP_5.3.0/com.ibm.cics.ts.doc/dfhtk/topics/dfhtk2c.html)을 구성하는 링크가 있습니다. 저는 CICS 전문가가 아니므로 거기에서 당신을 도울 수는 없습니다. – Gas

    답변

    0

    다음 솔루션은 제대로 작동하는지 테스트했습니다.

    아이디어는 CICSExecutorService#runAsCICS을 사용하여 SQL/DDL 문을 실행하는 것입니다.다음 확장자는 hibernate.hql.bulk_id_strategy 속성을 통해 등록됩니다.

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

    A : 새로운 JCICS의 API 버전이 이런 식으로 execute 방법의 CICS 분기를 단순화하는 것이 유용 할 수있는 Callable 수용 runAsCics 방법에 대한에 과부하를 가지고

    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); 
        } 
    } 
    

    주 몇 가지 대안을 시도했습니다 :

    1. 연결 획득 동작 (org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl#getConnection)이 작동하지 않았습니다. 연결이 주 스레드에서 사용될 때 이미 닫혔습니다.
    2. 전체 응용 프로그램 시작 (org.springframework.web.context.ContextLoaderListener#contextInitialized)을 래핑하면 클래스로드 문제가 발생합니다.

    편집 :는 결국 사용자 정의로 시작 (see project page on GitHub)에있는 모든 SQL/DDL을 실행하지 않습니다 Hibernate의 MultiTableBulkIdStrategy 구현을 갔다.

    0

    Liberty의 JPA 기능에 대한 CICS TS v5.3 지원이 최근 서비스 새로 고침 (2016 년 7 월)에서 제공되었습니다. 업데이트하기 전에 JPA를 응용 프로그램에서 실행하려고하면 사용자가 설명하는 것과 매우 유사한 문제가 발생합니다.

    최대 절전 모드를 실행 중이고 CICS 지원 스레드에 있지만 API 환경이 없으므로 (유형 2 JDBC 호출이 성공할 수 있음). 새로운 감지 로직은 DB2 JDBC 유형 2 드라이버 및 JPA와 함께 사용하기 위해 특별히 개발되었지만 독점적 인 것은 아닙니다. 이 업데이트는 최근 서비스 새로 고침시 제공되어보고있는 문제를 치료할 수 있습니다. 적용

    봅니다 : http://www-01.ibm.com/support/docview.wss?crawler=1&uid=swg1PI58375

    설명은 '표준 모드 자유'지원을위한라고하지만, 위에서 설명한대로 다른 개발이 포함되어 있습니다.