2013-08-23 2 views
3

우리는 websphere 7에서 최대 절전 모드, 스프링 및 DB2를 사용하는 응용 프로그램을 가지고 있습니다. 우리는 감사 트리거를 가지고 있으며 트리거가 로그인 한 사용자를 알 수 있도록 설정해야합니다 데이터베이스). 우리는 새로운 애플 리케이션에 이것을 설정하기위한 새로운 계획을 제안하여 새로운 트랜잭션에 자동으로 참여할 수있게했습니다. 우리는 트랜잭션 관리자를 무효화하고 doBegin에서 작업을 수행했습니다.사전 바인딩 된 JDBC 연결이 발견되었습니다

이러한 구성표는 한 앱에서 훌륭하게 작동했으며 두 번째 앱에서는 훌륭하게 작동했지만 지금은 몇 주 후로 일관되게 (동작이 간헐적이며 현지 개발에서 발생하지 않음) 바인드 된 JDBC Connection에서 오류가 발생했습니다. 온라인에서 보면 대부분의 게시물은 하나의 데이터 소스에 대해 두 개의 트랜잭션 관리자를 사용한다고 말합니다. 그것은 지금 우리가하고있는 것입니다.

나는 그가 주석과 AOP 기반 트랜잭션을 혼합했기 때문에 그것이 궁금한 게시물 하나를 읽었습니다. 이 응용 프로그램 중 일부는 않습니다. 나는 그 이론을 정말로 구입하지는 않지만 그것을 언급 할 것이라고 생각했다.

예외 :

Caused by: 
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! HibernateTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single HibernateTransactionManager for all transactions on a single DataSource, no matter whether Hibernate or JDBC access. 
at java.lang.Throwable.<init>(Throwable.java:67) 
at org.springframework.core.NestedRuntimeException.<init>(NestedRuntimeException.java:54) 
at org.springframework.transaction.TransactionException.<init>(TransactionException.java:34) 
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:475) 
at gov.usdoj.afms.umc.utils.hibernate.AfmsHibernateTransactionManager.doBegin(AfmsHibernateTransactionManager.java:28) 

코드 (예외가 super.doBegin에서 온다) (주) :

protected void doBegin(Object arg0, TransactionDefinition arg1) { 
    super.doBegin(arg0, arg1); 
    if (!Db2ClientInfo.exists()) { 
     clearDBProperty(); 
    } else { 
     setDBProperty(Db2ClientInfo.getClientUserId(), Db2ClientInfo.getClientApplicationId()); 
    } 
} 
private void setDBProperty(String uId, String appName) { 
    Session session = getSessionFactory().getCurrentSession(); 

    Properties props = new Properties(); 
    props.setProperty(WSConnection.CLIENT_ID, uId); 
    props.setProperty(WSConnection.CLIENT_APPLICATION_NAME, appName); 
    try { 
     Connection nativeConn = new SimpleNativeJdbcExtractor().getNativeConnection(session.connection()); 
     if (nativeConn instanceof WSConnection) { 
      WSConnection wconn = (WSConnection) nativeConn; 
      wconn.setClientInformation(props); 
     } else { 
      logger.error("Connection was NOT an instance of WSConnection so client ID and app could not be set"); 
     } 
    } catch (Exception e) { 
     throw new RuntimeException("Cannot set DB parameters!", e); 
    } 
} 
+0

http://stackoverflow.com/questions/12606257/spring-multiple-transaction-manager-issue – Gray

답변

4

방금 ​​나는 결코 대답하지 않았다는 것을 깨달았습니다. 예외는 Tx 매니저와 아무 상관이없는 것으로 밝혀졌습니다. 이 특정 EAR에는 동일한 데이터 소스를 가리키는 두 개의 앱이 있습니다. 분명히 이것은 최대 절전 모드를 혼란스럽게합니다. 우리는 언젠가 응용 프로그램을 분리 할 계획을 가지고 있지만 동일한 (이름 제외) 데이터 원본을 만들고 응용 프로그램을 개별적으로 가리키면 현재 문제가 해결됩니다.

1

트랜잭션 관리자를 수정하면 그것이 될 수도 대신에 쉽게 (? 더 나은) 데이터 소스 주위에 래퍼를 만들고 (스프링에서 DelegatingDataSource을 확장) 2 개의 getConnection 메소드를 오버라이드한다. 정리를 위해 프록시에서 연결을 랩핑하고 닫기 메소드를 인터셉트 할 수 있습니다.

그건 안전하고 (더 쉽게 추측) 방법 다음 트랜잭션 관리자와 피들 노력하고 래핑 된 데이터 원본을 사용하는 모든 기술 (JDBC, 최대 절전 모드, JPA 등) 작동합니다. (등록은 DataSource 인스턴스를 탐지하고 위임자로 간단히 래핑하는 BeanPostProcessor을 사용하여 수행 할 수 있습니다.)

이것이 급진적 인 경우 (라이브러리를 업데이트하는 대신 현재 응용 프로그램을 변경하는 것을 의미). 구성 문제 일 수 있으므로 구성 (및 DataSource 및 TransactionManager)을 한 번만로드하면되므로 빈 인스턴스를 복제하면 유사한 동작이 발생할 수 있습니다.

+0

과 관련이있을 수 있습니다. 왜 이것이 "안전한"이유인지 알 수 없습니다.그것은 똑같은 원칙처럼 보인다. 트랜잭션이 시작될 때까지 나는 그것을 수행하지 않는다. 실제로는 적절한 순간이다 (읽기 전용 연결은 감사 트리거와 마찬가지로 client_id를 설정할 필요가 없다). – user1187719

+0

그리고 예, 설정을 한 번만로드한다고 확신합니다. – user1187719

+0

누군가가 @Transactional을 잊어 버리거나 (pointcut가 일치하지 않는 경우) 속성이 설정되어 있기 때문에 더 안전합니다 (모두가 데이터 소스를 사용해야합니다). 그러나 IMHO는 물론입니다. 'doBegin' 메쏘드에 전달 된 첫번째 인자는'HibernateTransactionObject'이어야합니다. 이것은 ('super.doBegin()'다음에) 올바른 연결을 처리해야합니다. hibernate를 사용하는 대신에'HibernateTransactionObject'에서 이미 바인딩 된 연결을 사용하십시오. –

0

후손을 위해 방금이 문제가 발생했으며 여기에 대한 답변이 도움이되지 않았습니다. 우리는 그 안에 AOP 트랜잭션 관리자 정의를 가지고 핵심 XML 파일의 더블 가져 오기를 제거하여 문제를 해결 : 나는 같은 네임 스페이스를 중복이 트랜잭션 관리자가있을 원인이 있다고 생각하고

<tx:annotation-driven transaction-manager="..." 
    proxy-target-class="true" /> 

. 그것을 고치기 위해 우리는 수입품을 옮겨서 한 번 해보았습니다.

다른 사람에게 도움이되기를 바랍니다.

관련 문제