• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

@Transactional 위치와 적용에 대하여

24.03.21 18:19 작성 24.03.21 18:19 수정 조회수 90

0

[질문 내용]    
@Transactional
    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        bizLogic(fromId, toId, money);
    }
    
    public void bizLogic(String fromId, String toId, int money) throws SQLException {
        Member fromMember = memberRepository.findById(fromId);
        Member toMember = memberRepository.findById(toId);

        memberRepository.update(fromId, fromMember.getMoney() - money);
        validation(toMember);
        memberRepository.update(toId, toMember.getMoney() + money);
    }

안녕하세요. 강의 코드와 같이 accountTransfer을 실행했을때 트랜잭션이 잘 작동되어 오류가 발생했을때 롤백이 실행됩니다.

    @Transactional
    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        Member fromMember = memberRepository.findById(fromId);
        Member toMember = memberRepository.findById(toId);

        memberRepository.update(fromId, fromMember.getMoney() - money);
        validation(toMember);
        memberRepository.update(toId, toMember.getMoney() + money);
    }

이 코드 또한 그렇습니다.

    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        bizLogic(fromId, toId, money);
    }

    @Transactional
    public void bizLogic(String fromId, String toId, int money) throws SQLException {
        Member fromMember = memberRepository.findById(fromId);
        Member toMember = memberRepository.findById(toId);

        memberRepository.update(fromId, fromMember.getMoney() - money);
        validation(toMember);
        memberRepository.update(toId, toMember.getMoney() + money);
    }

하지만 이 코드에서 accountTransfer을 실행했을때 트랜잭션이 작동하지 않습니다.

스크린샷 2024-03-21 오후 6.03.35.png이유가 무엇일까요?

답변 1

답변을 작성해보세요.

1

y2gcoder님의 프로필

y2gcoder

2024.03.21

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

말씀해주신 문제는 @Transactional 은 프록시 방식의 AOP를 적용하기 때문에 발생하는 문제 중 하나입니다!

트랜잭션이 적용되려면 항상 프록시를 거쳐서 호출이 되어야 하는데, @Transactional이 걸리지 않은 메서드 내부에서 @Transactional 이 걸린 메서드를 호출하면 프록시를 거치지 않고 호출하기 때문에 트랜잭션이 작동하지 않습니다!

이 부분에 대해서는 스프링 핵심 원리 - 고급편섹션 13. 스프링 AOP - 실무 주의사항 을 참고해주시면 왜 작동하지 않는 것인지 이해하실 수 있을 거라 생각합니다!

감사합니다.