2011-11-17 8 views
4

저는 약간의 배경을 가지고 있습니다. 저는 최근에 수석 개발자가 퇴사 한 후 주요 프로젝트를 인수 한 새로운 개발자로서, 어떻게 구조화되었는지 완전히 이해할 수있게되었습니다. 내가 할 수있는 한 최선을 다해 문제를 설명하려고 노력할 것이다.@Transactional을 사용하는 메소드에서 스프링 빈 멈춤

이 응용 프로그램은 JMS 대기열에서 객체를 읽는 여러 MessageListner 스레드를 만듭니다. 객체가 수신되면 데이터는 비즈니스 로직을 기반으로 조작 된 다음 최대 절전 모드 EntityManager를 사용하여 오라클 데이터베이스에 저장 될 지속 객체에 매핑됩니다.

몇 주 전까지 만해도 프로젝트에 참여한 이후 지난 1 년 동안이 구성에 큰 문제가 없었습니다. 그러나 대기열 중 하나 (이 문제는이 특정 대기열과 격리되어 있음)의 경우 수신 된 객체를 처리하는 스프링 관리 Bean은 아래 메소드에서 중단됩니다. 디버깅을 통해 메소드 내 모든 작업이 완료되었지만 완료되면 중단됩니다. 이 문제를 해결하기 위해 몇 주 동안 노력한 끝에 저는이 문제로 제 밧줄 끝에 섰습니다. 이것에 대한 어떤 도움도 크게 감사 할 것입니다.

각 MessageListner는 자체 프로세서를 가지기 때문에이 행잉 방법은 하나의 큐에 들어오는 데이터에만 영향을줍니다.

@Transactional(propagation = Propagation.REQUIRES_NEW , timeout = 180) 
public void update(UserRelatedData userData, User user,Company company,...) 
{ 
    ... 
    .... 
    //business logic performed on user object 
    .... 
    ...... 
    entityMgr.persist(user); 

    //business logic performed on userData object 
    ... 
    .... 
    entityMgr.persist(userData); 

    ... 
    .... 

    entityMgr.flush(); 

} 

디버그 문을 삽입하여 메서드를 살펴보고 entityMgr.flush.()를 포함한 모든 작업을 완료했습니다.

답변

4

기본 데이터베이스에 커밋되지 않은 변경 사항이있을 때 이러한 문제가 발생할 수 있습니다.

다른 코드는 일괄 처리 작업 또는 유사 작업 이후에 실행하는 데 오랜 시간이 걸리는 트랜잭션 또는 트랜잭션 외부의 userData 테이블에 삽입/삭제 된 것으로 의심됩니다. 이 테이블을 참조하는 모든 코드를 분석하고 누락 된 @Transactional을 찾아야합니다.

+0

이것은 오래된 것입니다. 그러나 비슷한 문제가있는 경우에 대비하여 다시 설명하겠습니다.데이터베이스와 관련된 문제로 밝혀졌습니다. DBA와의 여러 차례 회의를 마침내 해결했습니다. – Rhouujin

+0

무엇이 문제였습니까? – Robocide

0

this answer 옆에있는 트랜잭션 —의 격리 수준을 확인하십시오. 너무 제한적일 수 있습니다.

update() 메서드가 영원히 중단 되나, 시간 초과가 발생하면 예외가 발생합니까?

+0

update 메소드는 영원히 정지되어 현재 수석 개발자와 협력하여 이것이 테이블에서 블로킹 문제인지 판단 할 수 있는지 확인합니다. – Rhouujin

1

불행히도 Propagation.REQUIRES_NEW과 동일한 문제가 있습니다. 제거하면 문제가 해결됩니다. 디버거는 커밋 메소드가 걸려 있다는 것을 보여줍니다 (@Transactional 애스펙트 구현에서 호출 됨).

문제는 응용 프로그램이 잘 작동하는 응용 프로그램 서버에 응용 프로그램을 배포 할 때 테스트 봄 컨텍스트에서만 나타납니다.

2

단위 테스트에 사용 된 트랜잭션 관리자가 JpaTransactionManager의 자바 독에서 ... 을 중첩 된 트랜잭션을 지원하지 않기 때문에 REQUIRES_NEW 테스트 환경에서 중단 될 수 있습니다 : 그래서 명확하게 호출하지 않는 경우

* <p>This transaction manager supports nested transactions via JDBC 3.0 Savepoints. 
* The {@link #setNestedTransactionAllowed "nestedTransactionAllowed"} flag defaults 
* to {@code false} though, since nested transactions will just apply to the JDBC 
* Connection, not to the JPA EntityManager and its cached entity objects and related 
* context. You can manually set the flag to {@code true} if you want to use nested 
* transactions for JDBC access code which participates in JPA transactions (provided 
* that your JDBC driver supports Savepoints). <i>Note that JPA itself does not support 
* nested transactions! Hence, do not expect JPA access code to semantically 
* participate in a nested transaction.</i> 

(당신의 XML의 설정에 @Java 설정) 또는 설정에 해당하는 플래그 :

txManager.setNestedTransactionAllowed(true); 

또는 드라이버가 세이브 포인트를 지원하지 않는 경우, 그것은 REQUIRES_NEW으로 문제를 얻기 위해 "정상"의

... 가 (일부는 exce을 선호 할 수 있습니다 ption "중첩 된 트랜잭션이 지원되지 않음")

관련 문제