inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링 DB 2편 - 데이터 접근 활용 기술

스프링 트랜잭션 전파7 - REQUIRES_NEW

외부 내부 모두 신규 트랜잭션인데, 외부커넥션을 먼저 반납하는경우

913

이용조

작성한 질문수 11

2

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

문득 궁금한점이 생겨서...

 

@Test
void inner_rollback_requires_new() {
log.info("외부 트랜잭션 시작");
TransactionStatus outer = txManager.getTransaction(new DefaultTransactionAttribute());
log.info("outer.isNewTransaction()={}", outer.isNewTransaction());

log.info("내부 트랜잭션 시작");
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
TransactionStatus inner = txManager.getTransaction(definition);
log.info("inner.isNewTransaction()={}", inner.isNewTransaction());

log.info("외부 먼저 트랜잭션 커밋");
txManager.commit(outer);

log.info("그다음 내부 트랜잭션 커밋");
txManager.commit(inner);
}

 

위와같이 외부 트랜잭션이 먼저 시작되고, 내부보다 먼저 커밋이나 롤백한 이후에

나중에 시작한 트랜잭션인 내부 트랜잭션의 커밋이라 롤백을 호출하면 IllegalStateException을 던지더라구요.

(사실 @Transactional을 이용하면 이런일이 발생하지 않게되어서 이상한 코드 인것같습니다만.., 내부트랜잭션에서 커밋이나 롤백을 누락하거나 / 멀티쓰레드 환경인데 커넥션을 파라미터로 받아서 사용한다거나 하면 겪게 될 수도 있을듯 해서요...)

사실 두 커넥션 간의 연관관계가 없다 생각했는데, 어떠한 이유로 연관이 있나보네요.

일단은 아직 고급편강의를 듣지 않았지만.. 고급편도 곧 들을 예정입니다. 고급편에서 확인할 수 있는 내용일까욤??

일단, 트랜잭션 동기화 매니저는 내부적으로 커넥션을 생성한 쓰레드로 그룹핑을 하여 관리한다고 생각하고.. 같은 쓰레드로컬 내에서 커넥션이 여러개 있을때, 먼저 생성된 커넥션이 먼저 반납되는 것 자체가 이상상태로 스프링은 취급한다 라고 생각하면 맞을까요..? 

 

질문을 다시요약해보면,

1. 트랜잭션 전파옵션을 PROPAGATION_REQUIRES_NEW로 하여 2개의 별도의 커넥션이 생성됨.

2. 한 쓰레드로 부터 생성된 커넥션은 2개인 상태.

3. 먼저생성된 커넥션의 커밋이 먼저 수행됨.

4. 나중에 생성된 커넥션의 커밋을 수행할때 illegalStateException 예외 발생.

 -> 두개의 커넥션간의 연관관계는 사실 없다고 생각드는데, 예외가 발생한것에 대해 의문점이 생깁니다!

5. 스프링은 동일한 쓰레드로 부터 여러 커넥션이 생성되었을때, 나중생성된 커넥션부터 순차적으로 커밋되지 않으면 이것 자체를 이상상태로 취급? 하는것인지 궁금합니다!

spring

답변 3

3

김영한

안녕하세요. 이용조님

여기서 어떤 문제가 발생할지는 저도 잘 모르겠습니다.

트랜잭션은 항상 순서대로 시작하고, 역순으로 종료하셔야 합니다.

감사합니다.

0

김승현

그 TransactionSynchronisationManager와 연관된 문제 같습니다. outer를 닫으면서 TransactionSynchronisationManager에 어떠한 side effect 를 남기는거 같습니다.

 

제 예상으로는

outer 트랜젝션 생성 시 모종의 방식으로 현 쓰레드와 key / value 형태로 묶이는거 같습니다.

차후 inner transaction 생성 시 스택 프레임 형태로 outer 위에 트랜젝션 컨텍스트가 생성되는거 같습니다.

그 후 outer -> inner 로 컨텍스트 전환이 있는 다음,

commit(outer)를 해버리면 inner로 주 context 가 전환되었더라도 outer transaction 가 flush 됨과 동시에 현 쓰레드와 묶인 key/value 마저도 사라지는거 같습니다..

일종의 inner transaction이 좀비 프로세스가 되는 느낌...? 같습니다..

0

최승호

음 그니깐 독립 되어 있더라도 살짝만 독립된거군요

0

김승현

저게 outer 에서 inner 를 생성시켜도 transaction synchronisation을 관리하는거 같습니다..

RepositoryTest의 패키지 위치가 domain인 이유

0

13

1

REQUIRES_NEW 해결 방법에 대해서 질문있습니다!!

0

25

1

update()에 사용하는 setter 질문드립니다.

0

43

1

SQL 중심적 개발의 문제점에 대한 질문

0

70

1

혹시 Containing 을 안쓰신 이유가 있을까요?

0

80

2

[공유] 스프링부트 4.x 버전 mybatis 연동

0

168

1

@repository 어노테이션

0

88

3

ItemService

0

55

1

논리 커밋, 물리 커밋 질문드립니다.

0

52

1

내부 트랜잭션 커밋은 필수인가요?

0

55

1

프록시 커넥션 객체를 반환할 때 생성하는건가요?

0

52

1

Transaction readOnly 성능 개선 (김영한님의 대한 감사인사)

2

175

2

JPQL 대신 네이티브 쿼리를 사용해야 하는 경우

0

76

1

@EventListener(ApplicationReadyEvent.class) 관련

0

86

1

트랜잭션 동기화 매니저와 데이터 소스

0

74

1

DB 관련 강의 개설 계획은 없으신건가요?

0

132

2

물리 트랜잭션 과 논리트랜잭션 용어를 맞게 이해한걸까요

0

92

1

스프링 3 버전 이상 rollbackFor 변경된듯요

1

109

1

트랜잭션 전파 질문.

0

86

1

프로젝트 오픈 에러

0

124

1

외부 트랜잭션에서 isNewTransaction이 false로 나오는거에 대해 질문드립니다

0

82

2

같은 스레드를 사용하면 트랜잭션 동기화 매니저는 같은 커넥션을 반환

0

70

1

h2 인메모리 테스트중 예약어 충돌날 경우 대처방법

0

99

1

커스텀aop와 트랜잭션을 같이 사용할때 우선순위에 관한 질문

0

94

2