저는 Spring의 트랜잭션 지원과 JPA (Hibernate)를 사용하여 엔티티를 유지합니다. 모든 것이 제대로 작동하지만 한 요청 내에서 부분 업데이트를 처리 할 때 막혔습니다.Spring 관리 트랜잭션 내의 JPA EntityManager 두 개?
모든 사용자 (HTTP) 요청에 대해 데이터베이스 항목에 로그 항목을 기록했습니다. "기본"비즈니스 엔티티가 실패합니다 (예 : 유효성 검증 오류로 인해). 따라서 첫 번째/주 트랜잭션은 롤백되지만 두 번째 (로그 작성)는 커밋해야합니다. 이 로그 항목을 작성하기위한 올바른 전파 레벨을 사용하여 작동하는 것 같다 :
@Repository
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class UserTracker extends ... {
@PersistenceContext private EntityManager em;
public void log(...) {
// create log entity and persist it
...
em.persist(log);
em.flush();
}
}
내 문제는 내가 처음과 두 번째 트랜잭션에 주입 같은 EntityManager를 얻을 수 있다는 점이다. 따라서 엔티티 관리자를 플러시 (두 번째 트랜잭션이 커밋 될 때 명시 적으로 또는 암시 적으로)하면 첫 번째 트랜잭션에서 내 더러운 비즈니스 엔터티를 플러시합니다.
어떻게 해결할 수 있습니까? 로깅 부분에 두 번째 깨끗하고 신선한 EntityManager를 사용하고 싶습니다. 프로그램 적으로 하나를 열 수 있다는 것을 알았지 만, 이것을하기위한 클리너/선언적 "Spring-way"가 있습니까?
편집 :
내 두 번째 트랜잭션이 내 주요 비즈니스 트랜잭션 내에 중첩 된 것으로, 사실에서 줄기 수있는 내 문제 : 나는 두 개의 트랜잭션을 직렬화 내 문제를 해결했습니다
|-------------- A --------------X <- Rollback of main business transaction (A)
|--- B ---| <- Commit of second log transaction (B)
:
|--------- A --------X |--- B ---|
이제 모든 것이 좋지만 호기심에서 벗어났습니다. 첫 번째 접근 방식을 고수한다면 제안 된대로 JDBC에 의지하지 마십시오. 두 번째 (중첩 된) 트랜잭션에 대한 엔티티 관리자를 구성하여 새로운 트랜잭션에 대해 새 트랜잭션을 얻을 수있는 방법은 무엇입니까? 이 작업을 수행 할 수 있습니까?
생각해 보면 다소 이상한 설정입니다. 로그를 작성하려고 할 때 내 주요 비즈니스 트랜잭션이 아직 열려 있습니다 (여기서는 Open-In-View 패턴을 사용하고 있습니다). 나는 부작용을 피하기 위해이 두 가지 트랜잭션을 직렬화 할 수있다. –