Spring/Lombok

@Transactional

JWonK 2022. 4. 29. 15:39
728x90
반응형

@Transactional 

스프링에서 지원하는 @Transactional 어노테이션을 이용해 선언적 트랜잭션 처리가 가능하다.

 

그렇다면, Transactional이 뭘까?

 


 

우선, 트랜잭션이란(Transaction)이란?

자바 로직이 수행되는 동안 모든 과정이 오류없이 진행되면 매우 좋겠지만, 그렇게 간단하게 모든 것이 잘 되는 경우는 매우 드물다. 이럴 때 트랜잭션을 이용하여 오류가 없는 경우에만 데이터 베이스에 변경사항을 저장하고, 진행 도중 오류가 발생하게 되면 지금까지 진행했던 모든 과정들을 원래 상태로 되돌려놓는다.

즉, 데이터베이스의 상태를 변경하는 작업 또는 한 번에 수행되어야하는 연산들이 오류 없이 잘 동작하였을 경우에만 데이터베이스에 반영하고 그렇지 않은 경우에는 처음 상태의 데이터베이스로 되돌려놓는다.

 

 

 

언제 사용될까?

일반적으로 DB 데이터를 등록/수정/삭제하는 Service메서드는 @Transactional을 필수적으로 가져간다.

메서드 내 Exception이 발생하면 해당 메서드에서 이루어진 모든 DB작업을 초기화 시킨다.

 

ex) save메서드를 통해 10개를 저장하려하였지만 5번째에 Exception이 발생할 경우 앞에 저장된 4개의 데이터도 모두 롤백시켜버린다. (정확히 말하면, 이미 저장했던 것을 롤백시킨다는 의미는 아니고, 모든 과정 및 처리가 오류없이 정상적으로 이루어졌을 경우에만 DB에 커밋한다)

 

 

 


Commit(커밋) : 해당 Connection의 요청을 완료하고 특별한 에러가 없다면 결과를 DB에 반영한다.

 

RollBack(롤백) : 해당 Connection 수행 중 예기치 않은 에러가 발생하였다면 모든 과정을 취소하고 DB를 Connection이 수행되기 이전상태로 변경한다.


 

 

id는 롤백되지 않는다.

주로 insert 작업을 할 때 id(식별자)가 자동으로 증가하도록 Auto Increment 옵션을 적용하곤 하는데, 트랜잭션에 포함된 insert 작업으로 인해 증가한 id는 트랜잭션이 롤백되어도 다시 감소하지 않는다.

 

Auto Increment 옵션은 트랜잭션의 범위 밖에서 동작하기 때문이다.

 

트랜잭션 범위 안에서 동작하면 같이 롤백되고 id도 순서대로 부여할 수 있기 때문에 편할 것 같은데 ?

--> 동시성 때문에 불가능하다.

 

ex) 여러 사람이 동시에 한 사이트에 회원가입을 하는 상황을 생각해보자.

 

각각 insert 문이 포함된 트랜잭션이 진행되는데, 중복된 아이디 혹은 올바르지 않은 양식의 아이디 입력 등 여러 요인으로 인해 트랜잭션이 실패할 수도 있고, 성공할수도 있다.

 

각 트랜잭션이 다른 사람의 회원 가입 트랜잭션 성공 여부를 기다렸다가 id를 부여받기엔 얼마나 기다려야 될 지 모르는 일이다.

 

따라서 Auto Increment는 트랜잭션과 별개로 동작한다.

 

 

 

 

@Transactional 옵션

  • isolation
    • 트랜잭션에서 일관성 없는 데이터 허용 수준을 설정한다
  • propagation
    • 트랜잭션 동작 도중 다른 트랜잭션을 호출할 때, 어떻게 할 것인지 저장하는 옵션
  • noRollbackFor
    • 특정 예외 발생 시 rollback하지 않는다.
  • rollbackFor
    • 특정 예외 발생 시 rollback한다.
  • timeout
    • 지정한 시간 내에 메서드 수행이 완료되지 않으면 rollback한다. (-1일 경우 timeout을 사용하지 않는다)
  • readOnly
    • 트랜잭션을 읽기 전용으로 설정한다.

 

 

 

+ 공부하면서 관련된 것을 학습하면 계속 업로드 할 예정입니다.

728x90
반응형