Spring Boot

Transaction

stophyeon 2024. 2. 14. 15:36
728x90

Transaction이란

Transaction이란 여러 Query를 하나의 작업으로 묶어주는 기능을 합니다.
예를 들어 비밀번호의 수정은 SELET, UPDATE 2개의 Query문이 모두 정상적으로 동작되야 하고
결제 서비스의 경우는 본인 계좌가 있는 DB에서 SELECT,UPDATE 와 상대방 계좌의 SELECT,UPDATE
Query문이 모두 정상적으로 실행되어야 결제 서비스가 완료됩니다. 
Transacton은 여러 Query문을 하나의 작업으로 묶어서 실행 중 하나의 Query문이라도 동작되지 않는다면 서비스 
전체의 문제가 발생하는 것을 해결하는 방법입니다.

 

Transaction와 영속성 컨텍스트

Transaction의 원리를 이해하기 위해서는 JPA의 영속성 컨텍스트에대해 알아야합니다.
이전에 말했듯이 영속성 컨텍스트는 DB와 어플리케이션 사이의 가상의 DB 역할을 합니다.
영속성 컨텍스트는 아래의 그림과 같은 구조를 가지고 있습니다.

영속성 컨텍스트의 관리를 받는 Entity의 장점은 아래와 같습니다.
1. 동일성 보장 - 영속성 컨텍스트의 1차 캐시에 있는 Entity 호출 시 같은 인스턴스를 반환하므로 동일한 인스턴스                               가 계속 반환됩니다.

2. 더티 체킹 - 영속성 컨텍스트에 저장된 Entity의 처음 상태를 저장한 스냅샷과 트랜젝션 실행 후 Entity의 상태를 
                       비교한 뒤 변경되었다면 쓰기 지연 SQL 저장소에 UPDATE Query문을 저장한뒤 트랜잭션 종료 후 
                       SQL 저장소의 Query문을 DB에 커밋합니다.
3.트랜잭을 지원하는 쓰기 지연 - 트랜잭션을 기능을 사용하면 SQL 저장소에 Query문들을 저장해 놓았다가
                                                    트랜잭션이 모두 종료된 후에 DB에 Query문들을 반영합니다. 
잠깐 다른 말을 하자면 제가 생각하기에 JPA에서 가장 중요한 기능을 고르라고 한다면
EntityManager, Entity Transaction을 고를 것입니다. 
EntityManager는 Entity를 영속성 컨텍스트에 조회,저장,삭제할 수 있도록 해줍니다.
하지만 대부분 EntityManager를 직접 사용해본 적은 없습니다. 이유는 @Repository에 EntityManager가 포함되어 있기 때문입니다. 즉, Repository에 메서드를 통해 조회한 Entity들은 이미 영속성컨텍스트의 관리를 받는 것입니다.
JPA에서 제가 위 기능을 중요하다고 생각하는 이유는 DB와 연관되어있기 때문입니다.
서버의 기능 중 DB를 통해 조회하고 Data를 추출하는 것이 다른 기능에 비해 자원의 소비가 많습니다.
때문에 성능을 개선시키려는 부분중 대다수가 DB와 관련되어 있습니다.
Query문의 개수를 줄이거나,  DB의 조회 속도를 빠르게 하기위해서 index를 사용하는 것등이 해당됩니다.

이제 다시 돌아와서 Transaction에대해 알아보겠습니다.
앞에서 영속성 컨텍스트를 말한 이유는 Transaction과 영속성 컨텍스트는 같이 동작하기 때문입니다.
여러 Query문을 하나의 동작으로 묶어주는 Transaction을 통해 영속성 컨텍스트는 SQL 저장소에 Query문들을 저장하고 한번에 DB에 반영합니다. 

 

@Transactional의 속성

Spring에서 Transaction을 선언적으로 사용할 수 있게 @Transactional을 제공합니다.
@Transactional을 선언한 메서드는 메서드 내부의 모든 Query문들은 트랜잭션이 종료되기 전까지 
쓰기 지연으로 인해 DB에 반영되지 않습니다. 만약 Query문 중 하나라도 에외가 발생한다면 Query문은 모두 DB에 반영되지 않습니다. 이를 RollBack이라고 합니다. 

Transactionaa 어노테이션에는 개발자가 직접 설정할 수 있는 속성값들이 있습니다.
1. Propagation -
트랜잭션이 선언된 곳이 여러 곳일 경우 어떤 트랜잭션을 사용할 것인지를 결정

2. Isolation -
동시에 여러 트랜잭션이 진행될 때에 트랜잭션의 작업 결과를 다른 트랜잭션에게 어떻게 노출할 것인지를 결정

3.  readOnly -
특정 트랜잭션 작업 안에서 쓰기 작업이 일어나는 것을 의도적으로 방지
 

 

Propagation

propagation=PROPAGATION.REQUIRED 기본설정값으로 트랜잭션이 선언된 부분이 있다면 해당 트랜잭션을 적용하고 없다면 새로운 트랜잭션을 생성
propagation=PROPAGATION. SUPPORTS 트랜잭션이 있다면 메서드가 참여, 없다면 트랜잭션 없이 실행
propagation=PROPAGATION. MANDATORY 트랜잭션이 없으면 예외 발생
propagation=PROPAGATION. REQUIRES_NEW 항상 새로운 트랜잭션을 생성
propagation=PROPAGATION. NOT_SUPPORTED 트랜잭션이 존재하면 현재 메서드가 실행되는 동안 트랜잭션이 일시 중단
propagation=PROPAGATION. NESTED 트랜잭션이 이미 존재하는 경우 새 트랜잭션이 생성되어 기존 트랜잭션 내에 중첩고
트랜잭션이 존재하지 않으면 새 트랜잭션이 생성

Isolation

isolation=Isolation.Read Uncommitted 동시에 실행된 트랜잭션에서 commit되지않은 데이터를 가져올 수 있음
isolation=Isolation. Read Committed 동시에 실행된 트랜잭션에서 commit된 데이터를 가져올 수 있음
isolation=Isolation. Repeatable Read 커밋되지 않은 데이터와 동시에 접근한 테이블의 값을 읽어올 때 다른값을 읽어오는 것을 방지
isolation=Isolation. Serializable 가장 높은 수준의 격리수준으로 접근한 행의 추가/삭제로 인한 데이터 불일치를 방지하고 Repeatable Read의 기능도 포함

readOnly

readOnly=true 읽기 전용 트랜잭션으로 선언, 쓰기 기능 발생시 예외발생
readOnly=false 기본 설정값으로 읽기와 쓰기 모두 가능

 

'Spring Boot' 카테고리의 다른 글

Repository 테스트 코드  (0) 2024.06.20
Swagger  (0) 2024.03.14
Test 코드  (2) 2024.01.27
ObjectMapper  (0) 2024.01.27
리액티브 프로그래밍  (0) 2024.01.15