2017-11-20 22 views
0

javaJPA에서 Play Framework 2.5.1을 사용하고 있으며 중첩 트랜잭션이 명시된대로 작동하지 않는 것으로 보입니다.Play Framework - JPA 중첩 트랜잭션이 작동하지 않습니다.

public TransactionEntity saveTransaction(TrasactionForm form) { 
    return japApi.withTransaction(() -> { //outer transaction 
     TransactionEntity t = jpaApi.withTransaction(() -> { //inner transaction 
      TransactionEntity entity = form.toEntity(); 
      return txnDao.saveTransaction(entity); 
     }); 
    return txnDao.getTransaction(entity.id); //should get the transaction from db, but throws exception saying no entity found 
    }); 
} 

실제 사례는 위의 예보다 약간 복잡합니다. 외부 트랜잭션이 있고 중첩 된 트랜잭션 내에서 엔티티를 저장하고 외부 트랜잭션에서 트랜잭션을 페치하려고하면 예외를 찾을 수없는 최대 절전 모드로 전환됩니다. 외부 트랜잭션은 DB에 대한 내부 트랜잭션의 쓰기를 볼 수 없습니다.

Play JPA를 디버깅하고 최대 절전 모드로 전환하면 모든 것이 정상적으로 작동합니다. 지연 때문입니까? 나는 그것이 기본 거래 원칙이기 때문에 일어날 것이라고 생각하지 않는다.

Play에서 중첩 된 트랜잭션을 지원하는 코드를 읽고 보았습니다. 그러나 단순한 경우에는 작동하지 않습니다.

감사의 말과 도움에 감사드립니다.

답변

1

두 개의 트랜잭션을 생성하는 것처럼 보이지만 부모 트랜잭션과 하위 트랜잭션이 있다는 의미에서 "중첩 트랜잭션"이 아닙니다. JPA doesn't support nested transactions.

두 개의 트랜잭션이 동시에 실행 중이며 (두 개의 별도 스레드로 트랜잭션을 작성한 경우처럼) 별도의 트랜잭션입니다. 한 트랜잭션이 다른 트랜잭션이 커밋 된 값을 볼 것인지 여부는 database transaction isolation level 및 JPA 캐싱에 따라 다릅니다. 예 : JPA로 한 트랜잭션의 값을 이미 읽은 경우 다른 트랜잭션에서 커밋 된 경우에도 캐시 될 수 있습니다.

커밋 된 값을 읽으려면 "내부"트랜잭션 코드에서 "외부"트랜잭션으로 정상 스칼라 값으로 반환하십시오. 또는 세 번째 트랜잭션을 실행하여 값을 읽을 수도 있습니다.

+0

설명해 주셔서 감사합니다. 약간 이상하다. 외부 트랜잭션이 있고 거의 실패하지 않는 경우도있다. 정확한 원인을 알 수 없다. - 주로 테스트 케이스에서 발생한다. 나는 Play 애플리케이션을 빌드하지 않도록 몇 가지 해결 방법을 가지고있다. 시각. 아마 그것이 이유 일 수 있습니다. –

+0

트랜잭션 격리 수준 및 기본 데이터베이스에 따라 행을 읽을 때 비 결정적 결과를 얻을 수 있다고 생각할 수 있습니다. –