본문 바로가기
JPA

JPA - 트랜잭션 매니저1 개요

by sinabeuro 2022. 3. 25.
728x90

 

트랜잭션이란?

트랜잭션이란 insert, update, delete 등 DB 변경에 해당하는 SQL 문을 처리하는 작업의 단위입니다.

기본적으로 SQL 명령문 하나를 실행하는 것에서부터 서비스 내 메소드 전체가 트랜잭션의 단위가 될 수 있습니다.

부모 트랜잭션 내부에 자식 트랜잭션이 있는 경우에 부모 트랜잭션으로 트랜잭션 단위가 묶이게 됩니다.

 

 

 

트랜잭션의 속성(ACID)

트랜잭션은 4가지 속성(ACID)을 기반으로 작동합니다.

 

Atomicity 원자성

원자성 - 부분적인 성공을 허용하지 않습니다. all or nothing

트랜잭션 내에 있는 모든 작업이 완료되거나 모든 작업이 완료되지 않아야 한다.

즉, 트랜잭션 내의 작업 중 하나라도 exception이 발생하면 트랜잭션 내의 모든 작업은 롤백(rollback)되어야 합니다.

 

Consistency 일관성

트랜잭션 중에 오류 없이 유효한 데이터만 데이터베이스에 저장되어야 합니다.

유효한 데이터만 저장함으로써 데이터 간의 정합성을 맞춥니다.

 

Isolation 독립성

트랜잭션 내에 데이터 조작은 다른 트랜잭션으로부터 독립성을 보장받습니다.

한 트랜잭션이 완료되기 전까지 다른 트랜잭션을 실행하지 않습니다.

성능 관련 이유로 가장 유연성 있는 제약조건입니다.

 

Durability 지속성

성공적으로 수행된 트랜잭션의 데이터는 영구적으로 보관됩니다.

 

 

 

트래잭션이 롤백되지 않는 경우

트랜잭션 내에 exception 발생하면 커밋이 취소되고 전체가 롤백됩니다. 

하지만 롤백되지 않는 경우도 존재하며, 개발자들이 실수하는 롤백이 되지 않는 경우를 짚어보겠습니다.

  • Checked Exception이 발생한 경우 
  • 메소드에서 트랜잭션이 걸린 외부 메소드를 참조할 경우

 

Checked Exception이 발생한 경우

https://madplay.github.io/post/java-checked-unchecked-exceptions 참조

Unchecked Exception은 RuntimeException 과 RuntimeException 을 상속한 exception 으로 구성됩니다.

그외에 RuntimeException 에 해당하지 않는 부류를 Checked Exception 이라고 인지해도 무방합니다.

 

트랜잭션 내에 Unchecked Exception 이 발생하면, 전체가 롤백됩니다.

반면, 트랜잭션 내에 Checked Exception 이 발생하면, 전체가 롤백되지 않습니다.

 

트랜잭션 내에 Checked Exception 이 발생해도 전체를 롤백시킬 수 있는 방법은 대표적으로 두가지가 있습니다.

첫번째는 try, catch 문을 이용해서 Checked Exception 이 발생하면, Unchecked Exception(RuntimeException) 으로 throw 시키면 됩니다.

두번째는 @Transactional 어노테이션 rollbackFor 속성을 이용하면 됩니다.

@Transactional(rollbackFor = Exception.class) 

위와 같이 rollbackFor 속성에 Exception 클래스를 지정하면 Checked Exception 이 발생해도 정상적으로 전체가 롤백됩니다.

 

 

클래스 내의 트랜잭션이 걸린 메소드를 다른 메소드가 참조할 경우

같은 클래스 내의 트랜잭션이 걸린 외부 메소드를 참조할 경우 참조된 메소드의 트랜잭션이 실행되지않고 롤백도 되지않습니다.

이는 스프링 컨테이너와 연관이 있습니다.

스프링 컨테이너는 빈으로 진입할 때 메소드에 걸려있는 어노테이션에 대해서만 처리하고,

메소드 내에서 참조하고 있는 외부 메소드들의 어노테이션은 읽지 않습니다.

그래서 참조한 메소드의 @Transactional 이 무시됩니다.

 

예시 코드를 살펴보면

...
@Service
@RequiredArgsConstructor
public class BookService {
    private final BookRepository bookRepository;
    private final AuthorRepository authorRepository;
    private final EntityManager entityManager;
//    @Transactional(rollbackFor = Exception.class)       // 체크드 익셉션이라도 롤백이 됨
    @Transactional
    public void putBookAndAuthor() {
        Book book = new Book();
        book.setName("JPA 시작하기");
        bookRepository.save(book);

        Author author = new Author();
        author.setName("martin");

        authorRepository.save(author);

        throw new RuntimeException("오류가 나서 DB commit이 발생하지 않습니다.");
    }

    // 빈 클래스 내부에서 외부를 호출할 때는 @Transactional 를 읽지 않는다.
    public void put() {
        this.putBookAndAuthor();
    }
	
}

put() 메소드를 호출하면 putBookAndAuthor() 메소드의 @Transactional 이 무시됩니다.

 

이를 해결하기 위해 부모 메소드에서 트랜잭션을 걸고, 외부 참조 메소드의 결과값을 체크하여 상황에 맞게 throw Unchecked Exception 처리를 하면 됩니다.

 

 

 

 

 

참고 사이트 

 

https://milenote.tistory.com/108

 

[ JPA ] 6-4. 트랜잭션 매니저 (TransactionManager)

Reference. 한 번에 끝내는 Java/Spring 웹 개발 마스터 초격차 패키지 Online 이전 글 더보기 더보기 1. Repository interface 메서드 - 1 2. Query Method 정의 및 실습 - 2 3. Entity 기본 속성 - 3 4. Entity..

milenote.tistory.com

 

https://ssmlim.tistory.com/45

 

[Spring] Spring Transaction 설정

DB를 다룰려면 트랜잭션이 매우 중요하다. 개념적으로는 중요성을 이해하고 있지만 실제 업무에서 트랜잭션을 관리해본적이 없다... 그래서 Transaction 설정방법과 propagation에 대해서만 작성함...

ssmlim.tistory.com

 

https://m.blog.naver.com/irene-fts/221901293248

 

[DAY113] Spring Transaction Manager

*Spring Transaction Manager : Service클래스에서 예외발생시 예외발생전에 실행된 모든 DAO메소드...

blog.naver.com

 

728x90

'JPA' 카테고리의 다른 글

JPA - 트랜잭션 매니저3 전파 속성  (0) 2022.03.25
JPA - 트랜잭션 매니저2 독립성(격리) 속성  (0) 2022.03.25
JPA - Entity Listener  (0) 2022.03.25
JPA - 연관 관계  (0) 2022.03.25
JPA - Entity의 기본 속성  (0) 2021.12.03

댓글