• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

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

20.11.17 10:13 작성 조회수 112

0

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

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

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

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

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

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

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

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

답변 3

·

답변을 작성해보세요.

1

soollung님의 프로필

soollung

질문자

2020.11.19

답변 감사합니다 :)

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님

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

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

그리고 zipkyh@naver.com으로 메일 보내주시면 도움을 드릴께요.

감사합니다.