동기

회사에서 배치 관련 작업을 하다가, 트렌젝션 관련한 이슈를 만난 적이 있었다. JPA를 사용하여 코딩을 하고 있었는데, 트렌잭션이 밀릴까봐 업데이트를 칠 때마다 sleep을 조금씩 주었는데, JPA를 사용하다 보니 업데이트를 치는 부분이 하나의 트렌젝션으로 모두 묶여서 배치가 끝나는 순간 DB로 날아갈까봐 걱정이 되었다.그래서 @Transactional 어노테이션을 사용했었는데, 트렌젝션을 한번쯤 정리해야 할 거 같다는 생각이 들었다.

@Transactional

선언적 트렌젝션을 사용하는 방법은 두 가지가 있다. 첫 번째는 tx 네임스페이스를 사용하는 건데, 이 글에서는 그 방법에 대해서는 다루지 않겠다.

먼저 <tx:annotation-driven /> 태그를 사용하면 등록된 빈 중에서 @Transactional이 붙은 클래스나 인터페이스/메소드를 찾아서 트랜젝션 어드바이스를 적용해준다.

@Transactional
public interface MemberDao {
    public void add(Member m);
 
    public void add(List<Member> members);
 
    public void deleteAll();
 
    @Transactional(readOnly=true)
    public long count();
}
  • 인터페이스에 @Transactional을 붙이면 인터페이스 안에 모든 메소드에 적용된다.
  • @Transactional 을 메소드에 붙이면 메소드 단위에만 적용할 수도 있다.
  • 우선순위는 클래스의 메소드 > 클래스 > 인터페이스의 메소드 > 인터페이스 순으로 설정이 우선적으로 적용된다.