인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

soollung님의 프로필 이미지
soollung

작성한 질문수

실전! 스프링 데이터 JPA

@Transaction 과 관련된 질문입니다~

해결된 질문

작성

·

177

0

안녕하세요 강의 잘 듣고 있습니다

문의가 있어서 질문 드립니다

 특정메소드에서 @Transactional(propagation = Propagation.REQUIRES_NEW) 라는 옵션이 있습니다. 

기존 트랜잭션에 영향을 받지 않는 신규 트랜잭션이 발생되는것이라고 알고 있는데

주입받은 entityManager 객체를 활용하여 저장하고자 하는 객체 persist() 를 수행하고 메소드가 종료되었을때

insert 쿼리가 발생할줄 알았는데..

부모 트랜잭션이 종료가 되서야 반영이 되네요. 

이를 해결할수 있는 방안이 있을까요?

답변 3

1

soollung님의 프로필 이미지
soollung
질문자

답변 감사합니다 :)

1

김영한님의 프로필 이미지
김영한
지식공유자

 확인을 해보았습니다.

스프링의 트랜잭션은 프록시 AOP 방식으로 동작합니다.

따라서 같은 클래스 안에서 같은 메서드를 호출하면 AOP가 동작하지 않습니다.

원본 코드

@Transactional
@Repository
public class BaseRepo {
final EntityManager em;

public BaseRepo(EntityManager em) {
this.em = em;
}

public void save(School school){
em.persist(school);
}

/**
* 부모 트랜잭션 시작
* @param school1
* @param school2
*/
public void savePairSchool(School school1, School school2){
em.persist(school1);
saveChildSchoolWithOtherTx(school2);
}

/**
* 자식 트랜잭션(신규) 시작
* - 예상처럼 신규 tx 가 동작되지 않고 기존 tx에 합류?
* @param school
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveChildSchoolWithOtherTx(School school){
em.persist(school);
}
}

여러가지 해결방안이 있지만 가장 확실한 방법은 별도의 리포지토리를 만드시고, 그쪽으로 다음 로직을 이동시키면 됩니다.

    @Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveChildSchoolWithOtherTx(School school){
em.persist(school);
}

그리고 새로만든 리포지토리를 주입 받으신 다음에 다음과 같이 호출하면 됩니다.

baseRepo2.saveChildSchoolWithOtherTx(school);

감사합니다.

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. soollung님

제 생각에는 정상 동작해야 하는데 뭔가 꼬인 것 같아요.

현재 상황을 재현할 수 있는, 완전히 새로운 예제 프로젝트를 하나 만들어주세요.

전체 프로젝트를 압축해서 올려주세요.

감사합니다.

soollung님의 프로필 이미지
soollung

작성한 질문수

질문하기