트랜잭션에 대하여...

Yu Seong Kim·2024년 3월 16일
0

SpringBoot

목록 보기
17/29

트랜잭션이 무엇인가

만약에 데이터베이스에서 데이터를 수정할 때, 에외가 발생한다면 데이터베이스의 데이터들을 수정하기 전 상태로 돌아가야 하며, 다시 수정 작업을 진행해야 합니다. 이렇게 여러 작업을 진행하다가 예외가 발생하였을때, 이전 상태로 롤백하기 위해 사용하는 것을 트랜잭션이라 합니다. 간단히 말하면 Transaction(트랜잭션)이란 쪼갤 수 없는 여러 작업들을 논리적으로 묶은 가장 작은 단위입니다. 트랜잭션 작업의 마무리는 크게 2가지로 나뉩니다.

  • 트랜잭션 커밋 -> 작업이 성공적으로 마무리 됨.
  • 트랜잭션 롤백 -> 작업을 취소하고, 이전의 상태로 돌림.

트랜잭션 특징

  1. 원자성(Atomicity)
    트랙잭션의 과정을 데이터베이스에 모두 반영되던지, 모두 반영되지 않아야 합니다. 하나라도 실패한다면 앞서 성공한 것들을원상 복구 시켜야합니다.

  2. 일관성(Consistency)
    트랜잭션의 작업 처리 결과는 항상 일관성 있어야 합니다.

  3. 독립성(Isolation)
    어떤 트랜잭션도 다른 트랜잭션의 작업에 끼어들 수 없습니다.

  4. 지속성(Durability)
    트랜잭션이 완료된다면, 결과는 영구적이어야 합니다.

선언적 트랜잭션

스프링부트에서는 @Transaction 어노테이션을 이용하여 간단하게 사용가능합니다.
이 방식을 선언적 트랜잭션이라 부릅니다. 대부분 클래스나 메서드 수준에서 추가해 사용하는 방식이 일반적입니다. 적용된 범위에서는 트랜잭션 기능이 포합된 프록시 객체가 생성되어 자동으로 커밋,롤백을 진행해줍니다.

@Transactional
public void addProduct(Product product) throws Exception {
	// 로직 구현
}

트랜잭션 옵션 정리

  1. isolation -> 트랜잭션에서 일관성없는 데이터 허용 수준을 설정합니다.

  2. propagation -> 트랜잭션 동작 도중 다른 트랜잭션을 호출할 때, 어떻게 할 것인지 지정하는 옵션입니다.

  3. noRollbackFor -> 특정 예외 발생 시 rollback을 하지 않습니다.

  4. rollbackFor -> 특정 예외 발생 시 rollback을 진행합니다.

  5. timeout -> 지정한 시간 내에 메소드 수행이 완료되지 않으면 rollback을 진행합니다. (-1일 경우 timeout을 사용하지 않는다)

  6. readOnly -> 트랜잭션을 읽기 전용으로 설정합니다.

isolation(격리레벨)

@Transactional(isolation=Isolation.DEFAULT)

DEFAULT : 기본 격리 수준

: 기본 격리 수준이며, 데이터베이스의 격리레벨을 따릅니다.

READ_UNCOMMITED (level 0) : 커밋되지 않는 데이터에 대한 읽기를 허용

: 어떤 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 B라는 아직 완료되지 않은(Uncommitted 혹은 Dirty)데이터 B를 읽을 수 있습니다.
-Problem1 - Dirty Read 발생

READ_COMMITED (level 1) : 커밋된 데이터에 대해 읽기 허용

: 어떠한 사용자가 A라는 데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터에 접근할 수 없습니다.
-Problem1 - Dirty Read 방지

REPEATEABLE_READ (level 2) : 동일 필드에 대해 다중 접근 시 모두 동일한 결과를 보장

: 트랜잭션이 완료될 때까지 조회를 하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정이 불가능 합니다.
: 선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 후행 트랜잭션이 갱신하거나 삭제가 불가능 하기 때문에 같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴합니다.
-Problem2 - Non-Repeatable Read 방지

SERIALIZABLE (level 3) : 가장 높은 격리, 성능 저하의 우려가 있음

: 데이터의 일관성 및 동시성을 위해 MVCC(Multi Version Concurrency Control)을 사용하지 않습니다.
(MVCC는 다중 사용자 데이터베이스 성능을 위한 기술로 데이터 조회 시 LOCK을 사용하지 않고 데이터의 버전을 관리해 데이터의 일관성 및 동시성을 높이는 기술입니다)
: 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터에 shared lock이 걸리므로 다른 사용자는 그 영역에 해당되는 데이터에 대한 수정 및 입력이 불가능합니다.
-Problem3 - Phantom Read 방지

트랜잭션 격리 수준의 필요성

당연히 레벨이 높아질 수록 데이터 무결성을 유지할 수 있습니다.
그러나, 무조건적으로 상위 레벨을 사용한다면 Locking으로인해 동시에 수행되는 많은 트랜잭션들이 순차적으로 처리하게 되면서 DB의 성능은 떨어지게 되며 비용이 높아집니다. 그렇다고 Locking의 범위를 줄이게 된다면 잘못된 값이 처리될 상황도 발생한다.
그렇기 때문에 최대한 효율적인 방안을 찾아 상황에 맞게 사용하는 것이 중요합니다.

propagation (전파속성)

@Transactional(propagation=Propagation.REQUIRED)

REQUIRED (Defualt)

이미 진행중인 트랜잭션이 있다면 해당 트랜잭션 속성을 따르고, 진행중이 아니라면 새로운 트랜잭션을 생성합니다.

REQUIRES_NEW

항상 새로운 트랜잭션을 생성한다. 이미 진행중인 트랜잭션이 있다면 잠깐 보류하고 해당 트랜잭션 작업을 먼저 진행합니다

SUPPORT

이미 진행 중인 트랜잭션이 있다면 해당 트랜잭션 속성을 따르고, 없다면 트랜잭션을 설정하지 않습니다.

NOT_SUPPORT

이미 진행중인 트랜잭션이 있다면 보류하고, 트랜잭션 없이 작업을 수행합니다.

MANDATORY

이미 진행중인 트랜잭션이 있어야만, 작업을 수행합니다. 없다면 Exception을 발생시킵니다.

NEVER

트랜잭션이 진행중이지 않을 때 작업을 수행합니다. 트랜잭션이 있다면 Exception을 발생시킵니다.

NESTED

진행중인 트랜잭션이 있다면 중첩된 트랜잭션이 실행되며, 존재하지 않으면 REQUIRED와 동일하게 실행됩니다.

noRollbackFor (예외무시)

@Transactional(noRollbackFor=Exception.class)

특정예외 발생 시 Rollback 처리 하지 않습니다.

rollbackFor (예외추가)

@Transactional(rollbackFor=Exception.class)

특정 예외 발생 시 강제로 Rollback

timeout (시간지정)

@Transactional(timeout=10)

지정한 시간 내에 해당 메소드 수행이 완료되지 않을 경우 rollback 수행
-1일 경우 no timeout
Default = -1

readOnly (읽기전용)

@Transactional(readonly = true)

true 시 insert, update, delete 실행 시 예외 발생
Default = flase

(rollbackFor = Exception.class)

@Transactional은 기본적으로 Unchecked Exception, Error 만을 rollback하고 있습니다. 그렇기 때문에 모든 예외에 대해서 rollback을 진행하고 싶을 경우
(rollbackFor = Exception.class) 를 붙여야 합니다.
그 이유는 Checked Exception 같은 경우는 예상된 에러이기 때문이고,
Unchecked Exception, Error 같은 경우는 예상치 못한 에러이기 때문입니다.

정리

트랜잭션의 많은 내용이 더 있지만, 당장 스프링부트를 사용하면서 궁금한 내용을 포스팅 해보았습니다.!!

참고
1. https://devkingdom.tistory.com/287
2. https://velog.io/@pp8817/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%B6%94%EC%83%81%ED%99%94-%EB%8F%99%EA%B8%B0%ED%99%94
3. https://velog.io/@byeongju/Spring-Transaction%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90

profile
인생을 코딩하는 남자.

0개의 댓글