• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

내부 호출에 대한 재질문

24.03.31 13:56 작성 조회수 68

1

제가 좀 헷갈려서 다시 질문을 좀 드립니다.

  1. @Transactional이 있으면 프록시 생성이 된다

  2. 그런데 내부 호출을 하면 대상 객체(this)의 메소드를 호출하니까 트랜잭션이 발생하지 않는다

그래서 문제이다. 이를 해결하기 위한 방법 중에서 제일 권장하는 것이 클래스를 분리하는 것이다

라고 이해를 했습니다.

 

그런데 실무에서는

@Transactional (<= 클래스 전체에 트랜잭션을 걸었다는 표현입니다 어떻게 했는지는 잘 모르겠지만...클래스에 걸린 것은 확실합니다)

class ServiceImpl implements Servcie {

public void mainMethod() { // 메인 메서드

deleteMethod(); // 내부 메서드 호출

insertMethod(); // 내부 메서드 호출

}

 

public void deleteMethod() {} // 내부 메서드

public void insertMethod() {} // 내부 메서드

}

보통 위와 같이 코딩을 자주 하는데 이때는 클래스에 @Transactioanl 어노테이션이 있어

전체 메서드에 @Transactional 이 적용된다는 것은 이해를 합니다.

 

"그런데 mainMethod()에서 deleteMethod()를 호출하면 내부 호출이라 대상 객체의 즉, ServiceImpl 클래스에서 deleteMethod()를 호출하므로 트랜잭션이 적용되지 않는다"

가 맞지 않나요?

 

아니면 굳이 클래스를 분리하지 않고 클래스 단위에 @Transactional 애노테이션을 적용시키면

내부 호출에 문제가 없다는 뜻인지?

 

글로 질문을 하기가 어렵습니다. 답변을 글로써 하시기는 더욱 더 어려우실 것 같은데

너무 궁금해서 다시 질문을 드리니 양해 바랍니다.

답변 1

답변을 작성해보세요.

0

y2gcoder님의 프로필

y2gcoder

2024.04.01

안녕하세요. gaabi1204님, 공식 서포터즈 y2gcoder입니다.

재질문에 대한 답변을 잘못 드릴까 싶어 전 질문과 답변을 다시 확인하고 왔습니다 🙂

전에 해주셨던 질문: https://www.inflearn.com/questions/1217560/%ED%94%84%EB%A1%9D%EC%8B%9C-%EB%82%B4%EB%B6%80-%ED%98%B8%EC%B6%9C-%EB%AC%B8%EC%A0%9C%EC%97%90-%EA%B4%80%ED%95%9C-%EC%A7%88%EB%AC%B8-%EC%82%AC%ED%95%AD

일단 이번 질문에 대해서 답변을 드리고 싶습니다!

1. @Transactional이 있으면 프록시 생성이 된다

2. 그런데 내부 호출을 하면 대상 객체(this)의 메소드를 호출하니까 트랜잭션이 발생하지 않는다

그래서 문제이다. 이를 해결하기 위한 방법 중에서 제일 권장하는 것이 클래스를 분리하는 것이다

라고 이해를 했습니다.

=> 정확하게 이해하셨다고 생각합니다!

 

그리고

@Transactional (<= 클래스 전체에 트랜잭션을 걸었다는 표현입니다 어떻게 했는지는 잘 모르겠지만...클래스에 걸린 것은 확실합니다)

=> 이 부분도 맞습니다. 본 강의 섹션 9. 스프링 트랜잭션 이해 > 트랜잭션 적용 위치 에서 학습하실 수 있습니다. (추가로 인터페이스와 구현 클래스 각각 붙였을 때의 우선순위도 학습하실 수 있습니다! 🙂 ). 이 때는 대상 클래스의 모든 메서드(public 접근 제어자,

image

"그런데 mainMethod()에서 deleteMethod()를 호출하면 내부 호출이라 대상 객체의 즉, ServiceImpl 클래스에서 deleteMethod()를 호출하므로 트랜잭션이 적용되지 않는다"

=> 이 부분에 대해서는 전 질문 답변에서도 드렸던 것 같습니다. 이미 트랜잭션이 걸려있는 외부 메서드를 호출했고, 그 내부에서 다른 메서드를 호출한다면 그 역시 트랜잭션 내부에 있기 때문에 트랜잭션이 걸린 상황입니다. 위에 적어주신 코드를 예제로 해보자면

class ServiceImpl implements Servcie {

    public void mainMethod() { // 메인 메서드

        deleteMethod(); // 내부 메서드 호출

        insertMethod(); // 내부 메서드 호출

    }

 
    @Transactional
    public void deleteMethod() {} // 내부 메서드

    @Transactional
    public void insertMethod() {} // 내부 메서드

}

이런 식으로 되어 있고 mainMethod를 다른 곳에서 호출한다면 mainMethod()는 트랜잭션이 걸려있지 않은 상태로 내부호출을 하기 때문에 말씀하신 것처럼 트랜잭션이 걸리지 않게 됩니다. 이부분은 위에 말씀드린 같은 챕터의 트랜잭션 AOP 주의 사항 - 프록시 내부 호출1, 2 을 복습하시는 것을 권장합니다!

 

 

 

 

감사합니다.

gaabi1204님의 프로필

gaabi1204

질문자

2024.04.01

답변 감사드립니다. 이제 이해가 되었습니다.

  1. 클래스 단위로 @Transactional이 걸리면 내부 호출 문제는 발생하지 않는다. 모든 메소드에 @Transactional이 걸려 있기 때문에...

  2. 메소드 단위로 @Transactional이이 걸렸을 때 @Transactional이 없는 메소드가 호출되면 내부 호출 문제가 발생한다

이런 의미로 이해를 하면 되는거죠?

y2gcoder님의 프로필

y2gcoder

2024.04.01

현 요구사항에서는 그렇게 이해하셔도 될 것 같습니다!