inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

트랜잭션 AOP 주의 사항 - 프록시 내부 호출1

프록시 호출 관련 질문

334

chaelynjang

작성한 질문수 24

0

안녕하세요 강사님

좋은 강의 감사드립니다.

참여했던 실무 프로젝트에서 @Transactional 을 잘 이해하지 못한 채 사용했던 적이 있습니다.

특정 서비스의 한 메소드에서 @Transactional을 선언하고 해당 메소드가 여러 작업을 하기 때문에 다른 메소드를 호출하는 방식이었습니다.

이때 저는 트랜잭션의 특징을 잘 몰라서 두 메소드에 다 @Transactional을 선언했었습니다.

예시)

@Transactional

public void ex1() {

...

// 로직 수행 후 다른 메소드 호출

ex2();

}
@Transactional

public void ex2() {

// 로직 수행

}

테스트를 하는데 로직 수행중 ex1에서 에러가 나든 ex2에서 에러가 나든 트랜잭션 롤백이 안됐었는데 이런 케이스는 무엇이 원인인지 알려주실 수 있나요?
강의에서처럼 ex1이 아예 @Transactional이 선언되어 있지 않았다면 롤백이 안되는게 맞다고 생각이 드는데 저는 두 메소드 다 선언했었거든요,,

확인해주시고 답변 주시면 정말 감사드리겠습니다ㅠ

(혹시나 해서 강의 코드의 externalCall 메소드에 트랜잭션 선언해보고 테스트 돌려봤는데 트랜잭션 적용 되더라고요)

+추가 질문으로 이런 경우에는 ex1 메소드에만 @Transactional을 선언하면 될까요?

spring

답변 2

1

김영한

안녕하세요. chaelynjang님

동작하는 코드가 있어야 정확한 상황을 파악할 수 있겠지만 이런 경우는 트랜잭션 AOP 자체가 동작하지 않는 경우들이 있습니다. 지금은 스프링 부트가 트랜잭션 AOP들을 자동으로 등록해주지만 과거에는 직접 이런 부분을 다 관리했는데, 해당 코드가 잘 반영되어 있지 않다면 트랜잭션 자체가 걸리지 않습니다.

추가 질문: 네 ex1()에만 거시면 됩니다.

도움이 되셨길 바래요.

1

chaelynjang

감사합니다 강사님

저도 코드가 정확하게 잘 기억나지는 않지만

강의에서 말씀하신 것처럼 두 메소드 중 하나가 public 메소드가 아니었거나 체크예외가 발생해서 커밋되었을 수도 있었던 것 같아요

나머지 강의를 계속 듣다보면 트랜잭션이 제대로 롤백되지 않은 여러 이유를 찾을 수 있을 것 같습니다 :-)

항상 좋은 강의 감사드려요 정말 많이 배우고 있습니다.

감사합니다.

 

1

궁금이

선생님. 저 프록시 내부호출의 문제점에 대해 좋은 예시를 발견한 것 같습니다.

결론적으로 말하자면, 그렇게 되게끔 프록시가 만들어 졌다는 겁니다.

 

무슨 말이냐 하면, @Test의 @BeforeEach를 예를 들어

@BeforeEach
public void before(){
    log.info("before");
}

@Test
void check(){
    proxyCheck();
    proxyCheck();
}

@Test
void proxyCheck(){
    log.info("aop class={}", basicService.getClass());
    Assertions.assertThat(AopUtils.isAopProxy(basicService)).isTrue();
}

@BeforeEach는 각 @Test를 실행하면 꼭 한번 씩 실행이 되잖아요?

근데 check에서 @Test가 붙은 proxyCheck()를 두번이나 호출하여, @BeforeEach가 총 3번 호출되어야 하지만 1번만 호출 됩니다.

 

이런 것 처럼, 프록시도 "외부에서 처음 들어온 메소드 호출에서 한번만" 으로 동작되도록 설계가 된 것 같습니다.

 

좀 다르긴 할 것 같습니다.

물어보니까 @Test는 프록시가 아니라고 하고, @Test의 기능은 클래스 전체를 실행했을 때 @Test인 것을 실행토록 하는 거니..

 

좀 다르지만, 좋은 예시 같습니다.

1

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다.

처음에 ex1 메소드에만 @Transactional을 선언하셨을 때 롤백이 되지 않았다는 것은 롤백이 필요한 상황이 발생하지 않았거나 롤백이 제대로 처리되지 않은 것일 수 있습니다. 두 메소드 중 하나에서 예외가 발생하면 트랜잭션은 롤백되어야 합니다. 다만, 예외가 발생하지 않는 경우에는 롤백이 되지 않습니다.

이 경우가 왜 발생했는지 정확한 원인 파악은 어려우나, @Transactional 어노테이션을 두 메소드에 모두 선언했다는 것은 두 메소드가 독립적으로 트랜잭션을 처리한다는 것을 의미합니다. 따라서 ex1에서 예외가 발생한다고 해도 ex2는 이미 별도의 트랜잭션으로 처리가 완료되어 롤백되지 않은 것입니다.

해결책으로는 ex2 메소드에서는 @Transactional 어노테이션을 제거하고, ex1 메소드에서만 @Transactional 어노테이션을 유지하는 것이 좋습니다. 이렇게 하면 ex1에서 예외가 발생하면 전체 메소드 수행이 롤백되므로 문제가 발생할 가능성이 줄어듭니다.

답변이 도움이 되셨길 바랍니다. 감사합니다.

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

0

36

2

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

0

31

1

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

0

49

1

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

0

75

1

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

0

86

2

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

0

183

1

@repository 어노테이션

0

91

3

ItemService

0

59

1

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

0

54

1

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

0

57

1

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

0

55

1

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

2

180

2

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

0

80

1

@EventListener(ApplicationReadyEvent.class) 관련

0

89

1

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

0

77

1

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

0

133

2

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

0

94

1

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

1

113

1

트랜잭션 전파 질문.

0

87

1

프로젝트 오픈 에러

0

126

1

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

0

84

2

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

0

74

1

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

0

105

1

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

0

98

2