끄적끄적 코딩일지

[Spring 기초] 트랜잭션 본문

Spring

[Spring 기초] 트랜잭션

BaekGyuHyeon 2022. 6. 6. 16:17

트랜잭션(Transaction)이란?

트랜잭션(Transaction)이란 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위를 뜻한다.

 

여기에서 상태를 변화시킨다는것은 Query문을 발생시켜 데이터베이스의 데이터를 수정하는것을 의미한다.

 

예를들어 돈을 송금한다고 하면 계좌에서 돈을 빼고 -> 송금 계좌에 돈을 더하고 -> 기록을 생성 하는 과정을 거친다고 하자. 송금이라는 작업 하나지만 실제로 Update 두번 Insert 한번의 Query가 수행된다. 이러한 작업단위가 하나의 트랜잭션이다.

 


트랜잭션의 특징

트랜잭션은 크게 4가지로 구분한다.

1. 원자성(Atomicity)

트랜젝션은 데이터베이스에 모두 반영되던가, 전혀 반영되지 않아야 한다. 즉 작업을 수행을 했을때 작업의 일부만 반경되는 현상이 있으면 안된다.

만약 트랜잭션단위로 데이터가 처리되지 않는다면 데이터 처리 시스템을 이해하기가 쉽지 않고 오작동시 원인을 찾기 힘들어진다.

 

2. 일관성(Consistency)

트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다. 트랜잭션이 진행되는동안 데이터베이스가 변경되더라도 처음 참조한 데이터베이스로 진행한다.

 

3. 독립성(Isolation)

둘 이상의 트랜잭션이 동시에 실행되고 있을경우 하나의 트랜잭션에 다른 트랜잭션이 연산에 끼어들 수 없다.

 

4. 지속성(Durability)

트랜잭션이 성공적으로 완료됬을 경우, 결과는 영구적으로 반영되어야 한다.


Commit과 Rollback

Commit이란 작업이 성공적으로 끝났을경우 데이터베이스에 결과를 반영하기위해 해당 트랜잭션을 완료처리하는것을 의미한다.

 

Rollback이란 작업이 비정상적으로 종료되었을경우 트랜잭션을 처음부터 다시 시작하거나 수행된 결과를 전부 혹은 일부를 취소시킨다.


Spring에서 Transaction 사용하기

스프링 상에서 Transaction을 사용하는것은 쉽다.

사용하는 Service, 혹은 Controller에 @Transactional 을 붙이면 된다.

기본적으로는 Auto-commit mode로써 쿼리문을 한번 수행될때마다 commit한다.

@Service
public class CustomService{
    @Transactional
    public void testLogic(){
        ....
    }
}
@Controller
public class CustomController{
    @Transactional
    @GetMapping("/")
    public String doSomething(){
        ....
    }
}

Transactional 속성


isolation (격리레벨)

  • DEFAULT 
    • DB 설정을 따른다.
  • READ_UNCOMMITTED
    • 각 트랜잭션에서 변경내용을 commit이나 rollback 여부와 상관없이 해당 데이터를 읽을 수 있다.
    • 데이터를 읽은후 데이터가 변경되는 Dirty Read문제를 발생시킬 수 있다.

  • READ_COMMITED
    • Commit된 데이터만 읽을 수 있는 격리수준이다.
    • Commit전에 변경된 데이터를 읽으려 하면 변경전 데이터를 제공한다.  
    • RDB에서 기본적으로 사용되고 있는 격리 수준이다.
    • Dirty Read같은 현상은 발생하지 않는다.

 

  • REPEATABLE_READ
    • 선행트랜잭션이 읽은 데이터는 트랜잭션이 종료할때까지 후행 트랜잭션이 갱신하거나 삭제를 금지한다.
    • 후행 트랜잭션이 완료되어도 선행트랜잭션이 완료될때까지 변화는 반영되지 않는다.

  • SERIALIZABLE
    • 선행 트랜잭션이 완료되기 전까지 후행 트랜잭션 실행 자채를 막는다.
    • 데이터 관련해서 문제가 발생할 확률이 가장 낮지만 성능 면에서도 가장 낮다.
    • 데이터베이스에서는 거의 사용되지 않는다.

사용예시 @Transactional(isolation=Isolation.SERIALIZABLE)


readOnly

  • True 인 경우 Insert,Update,Delete 시 예외가 발생한다.

사용 예시 : @Transactional(readOnly= true)


noRollbackFor

  • 특정 예외 발생시  rollback처리를 안하도록 할 수 있다.

사용 예시 :  @Transactional(noRollbackFor=Exception.class)


rollbackFor

  • 특정 예외 발생시 강제로 rollback처리를 할 수 있다.

사용 예시 :  @Transactional(rollbackFor=Exception.class)


timeout

  • 지정한 시간내에 commit이 되지 않을경우 rollback수행

사용 예시 :  @Transactional(timeout=10)


propagation

  • 이미 진행되고 있는 트랜잭션에서 다른 트랜잭션을 호출할때 어떻게 처리할지 설정할 수 있다.
@Service
public class SomeService{
    @Transaction
    public void test(){
        ....
    }
    @Transaction
    public void test2(){
        ....
        test();
        ....
    }
}

 

 

  • PROPAGATION_REQUIRED(기본값)
    • 부모 트랜잭션이 존재한다면 부모 트랜잭션으로 합류, 없다면 새로운 트랜잭션 생성
    • 중간에 rollback이 발생한다면 하나의 트랜잭션이기 때문에 진행사항이 모두 rollback

  • PROPAGATION_REQUIRED_NEW
    • 새로운 트랜잭션을 생성하여 처리
    • 각각의 트랜잭션이 rollback되더라도 서로에 영향을 주지 않는다.

  • PROPAGATION_MANDATORY
    • REQUIRED처럼 부모 트랜잭션에 합류하지만 부모 트랜잭션이 없다면 예외를 발생시킨다. 즉 트랜잭션 안에서만 실행 가능하다.

  • PROPAGATION_NESTED
    • 부모 트랜잭션이 존재한다면 중첩 트랜잭션을 생성
    • 중첩 트랜잭션은 부모트랜잭션이 commit될때 함깨 commit된다.
    • 중첩 트랜잭션에서 rollback발생시 중첩 트랜잭션 내용만 rollback된다.
    • 부모 트랜잭션이 없을시 새로운 트랜잭션을 생성한다.

  • PROPAGATION_NEVER
    •  트랜잭션을 허용하지 않는다. 즉 부모 트랜잭션이 있다면 예외를 발생시킨다.

  • PROPAGATION_SUPPORTS
    • 부모 트랜잭션이 있다면 합류하나 없다면 트랜잭션 없이 진행
  • PROPAGATION_NOT_SUPPORTED
    • 부모 트랜잭션이 있으면 해당 트랜잭션이 끝날때까지 보류후 실행

 

사용 예시 @Transactional(propagation=Propagation.REQUIRED)


참고 및 이미지 출처

https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation

 

트랜잭션의 격리 수준(isolation Level)이란?

 

nesoy.github.io

https://deveric.tistory.com/86#recentComments

 

[Spring] 트랜잭션의 전파 설정별 동작

트랜잭션의 전파 설정이란 Spring에서 사용하는 어노테이션 '@Transactional'은 해당 메서드를 하나의 트랜잭션 안에서 진행할 수 있도록 만들어주는 역할을 합니다. 이때 트랜잭션 내부에서 트랜잭

deveric.tistory.com

 

'Spring' 카테고리의 다른 글

[Spring] Spring Security + JWT  (0) 2022.06.08
[Spring 기초] Scope 사용하기  (0) 2022.06.07
[Spring 기초] Bean 생명주기 콜백  (0) 2022.06.06
[Spring 기초] MVC 패턴  (0) 2022.06.05
[Spring 기초] Hibernate 다루기  (0) 2022.06.05