10분 테코톡 트랜잭션을 보고 정리한 내용입니다.
Spring @Transactional 속성들
- Table 16.3. @Transactional Settings
PropertyTypeDescription
value | String | Optional qualifier specifying the transaction manager to be used. * 사용할 PlatformTransactionManager의 식별자 * 트랜잭션 관리자 빈의 이름이나 제한자(qualifier) |
propagation | enum: Propagation | Optional propagation setting. * 트랜잭션 전파 설정 |
isolation | enum: Isolation | Optional isolation level. * 트랜잭션 격리 레벨 |
readOnly | boolean | Read/write vs. read-only transaction * 읽기/쓰기 트랜잭션 or 읽기 전용 트랜잭션 |
timeout | int (in second, 초 단위) | Transaction timeout. * 트랜잭션 타임아웃시간. * 지정한 시간 내에 해당 메소드 수행이 완료되이 않은 경우 rollback 수행. * -1일 경우 no timeout |
rollbackFor | Array of Class objects, which must be derived from Throwable. * Throwable'의 하위 'Class' 객체의 배열. |
Optional array of exception classes that must cause rollback. * 롤백을 유발하는 예외 클래스의 배열. * 이걸 지정한 예외가 발생하면 롤백이 된다. |
rollbackForClassName | Array of class names. Classes must be derived from Throwable. * 클래스 이름의 배열 * 'Throwable'에서 의 하위 클래스 |
Optional array of names of exception classes that must cause rollback. * 롤백을 유발하는 예외 클래스 이름의배열 * 예외 클래스 이름을 지정 |
noRollbackFor | Array of Class objects, which must be derived from Throwable. * 클래스 이름의 배열 * 'Throwable'에서 의 하위 클래스 |
Optional array of exception classes that must not cause rollback. * 롤백을 하지 않을 예외 클래스의 배열 * 지정한 예외의 발생 시 Rollback 처리되지 않음 |
noRollbackForClassName | Array of String class names, which must be derived from Throwable. * 클래스 이름의 배열 * 'Throwable'에서 의 하위 클래스 |
Optional array of names of exception classes that must not cause rollback. * 롤백을 하지않는 예외 클래스 이름의배열 * 지정한 예외의 발생 시 Rollback 처리되지 않음 |
- 스프링은 디폴트로 UnCheckedException 과 Error에 대해서 롤백 정책을 설정
- 반면에 예외가 전혀 발생하지 않거나 체크 예외가 발생하면 커밋한다.
- 체크 예외를 커밋 대상으로 삼은 이유는 체크 예외가 예외적인 상황에서 사용되기보다는 리턴 값을 대신해서 비즈니스적인 의미를 담은 결과를 돌려주는 용도로 많이 사용되기 때문이다.
- 스프링에서는 데이터 액세스 기술의 예외는 런타임 예외로 전환되어 던져지므로 런타임 예외만 롤백 대상으로 삼은 것
Transaction
- 여러 쿼리를 논리적으로 하나의 작업으로 묶어주는 것
- commit: 트랜잭션으로 묶인 모든 쿼리가 성공하여 트랜잭션 연산 결과를 DB에 반영한다.
- rollback: 쿼리 실행 결과를 취소하고 DB의 상태를 트랜잭션 이전 상태로 되돌린다.
트랜잭션의 성질
ACID
트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질
- Atomicitiy(원자성)
- 트랜잭션은 DB에 모두 반영되거나, 전혀 반영되지 않아야 한다.
- 완료되지 않은 트랜잭션의 중간 상태를 DB에 반영해서는 안 된다.
- Consistency(일관성)
- 트랜잭션 작업처리결과는 항상 일관성 있어야 한다.
- 데이터베이스는 항상 일관된 상태로 유지되어야 한다.
- Isolation(독립성)
- 둘 이상의 트랜잭션이 동시 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다.
- Durability(지속성)
- 트랜잭션이 성공적으로 완료되었으면 결과는 영구히 반영되어야 한다.
- 커밋이 되었다면, 정전과 같이 예상치 못한 문제가 발생 되었더라도 데이터는 반영된 그대로 남아있어야 한다.
- ACID는 이론적은 보장해야할 성질이다. 실제로 때로는 성능을 위해 성질 보장이 완화되기도 한다.
트랜잭션 격리 수준
- 동시에 DB에 접근할 때 그 접근을 어떻게 제어할지에 대한 설정 - 동시성 제어
- 격리 수준이 높아질수록 데이터 정합성은 좋아지나 동시성 성능이 떨어진다.
레벨DIRTY READNON-REPEATABLE READPHANTOM READ
종류 | 레벨 | DIRTY READ | READNON-REPEATABLE READ | PHANTOM READ |
READ UNCOMMITTED (커밋되지 않은 읽기) | 0 | 발생 (O) | 발생 | 발생 |
READ COMMITED (커밋된 읽기) | 1 | 없음 | 발생 | 발생 |
REPEATABLE READ (반복 가능한 읽기) | 2 | 발생 | 발생 | 발생 (InnoDB는 없음) |
SERIALIZABLE (직렬화 가능) | 3 | 없음 | 없음 | 없음 |
- READ UNCOMMITTED의 격리 수준이 가장 낮고 SERIALIZABLE의 격리 수준이 가장 높다
1. Dirty Read
이것은 트랜잭션 처리된 작업 의 중간 결과를 볼 수 있는 현상을 말한다.
즉, commit되지 않은 정보를 볼 수 있는 현상을 말하는 것으로 Read Uncommitted Isolation Level일 때 발생하는 Read 현상이다.
2. Non-Repeatable Read
이것은 한 트랜잭션안에서 같은 쿼리를 두번 실행 했을 때, 다른 값이 나오는 Read 현상을 말하는 것으로, 하나의 트랜잭션안에서 여러 스냅샷이 사용되는 경우를 말한다. Read-Committed 이하의 Isolation Level에서 나오는 현상이다.
이 현상은 특정 데이터에 대한 수정이 발생하여 나타나는 Read현상을 말한다.
3. Phantom Read
이것은 하 트랜잭션 안에서 첫번째 쿼리 수행 결과와 두번째 쿼리 수행 결과가 다른것을 나타내는 것인데 외부에 동시에 실행중인 트랜잭션의 Insert 작업에 의해 발생하는 Read현상을 말한다. 즉, 결과 범위에 속하지 않은 레코드가 외부 작업에 의해 있을 수도 있고, 없어질 수도 있다는 것을 뜻한다.
READ-UNCOMMITTED
- 커밋되기 전의 트랜잭션의 데이터 변경 내용을 다른 트랜젝션에서 읽는 것을 허용한다.
- 트랜잭션 A가 10번 사원의 나이를 27살에서 28살로 변경후 아직 commit하지 않았다.
- 동시에 실행되고 있는 트랜젝션 B에서 10번사원의 나이를 조회하면 28살로 조회된다. (dirty read)
- 트랜잭션 A가 rollback 한다.
- 트랜잭션 B는 10번 사원이 여전히 28살이라고 생각하고 로직을 수행한다.
- Dirty read, Non repeatable read, Phantom read 가 발생한다.
READ-COMMITTED
- 커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회가 가능하다.
- 트랜잭션 B가 10번 사원의 나이를 조회하면 27살로 조회된다.
- 트랜잭션 A가 10번 사원의 나이를 27살에서 28살로 변경후 commit한다.
- 트랜잭션 B가 다시 10번사원의 나이를 조회하면 28살로 조회된다. (non repeatable read)
- Non repeatable read, Phantom read 가 발생한다.
REPEATABLE-READ
MYSQL) 트랜잭션 마다 ID를 부여하여 트랜잭션 ID보다 작은 트랜잭션에서 변경한 내용만 조회한다.
- 트랜잭션이 시작되고 종료되기 전까지 한 번 조회한 값은 계속 같은 값이 조회된다.
- 트랜잭션 A를 시작하고 10번 사원의 나이를 조회하면 27살로 조회된다.
- 트랜잭션 B를 시작하고 10번 사원의 나이를 27살에서 28살로 변경한다.
- 트랜잭션 A가 10번 사원의 나이를 조회하면 27살로 조회된다. (트랜잭션 B의 ID가 더 작다.)
- 트랜잭션 B가 11번 사원의 정보를 insert한다.
- 트랜잭션 A가 모든 사원의 정보를 조회하면 10, 11번 사원이 조회된다. (phantom read)
- Phantom read 가 발생한다.
SERIALIZABLE
- 가장 높은 격리수준으로 트랜잭션에서 사용하는 데이터를 다른 트랜잭션에서 접근할 수 없다.
- 동시 처리 성능이 가장 떨어지지만 정합성 문제가 전혀 발생하지 않는다.
Dirty Read, NoN-Repeatable Read, Phantom Read
DIRTY READ - commit되지 않은 변경사항을 읽는다.
- 더티페이지(메모리에는 변경이 되었지만 디스크에는 아직 변경이 되지 않은 데이터)에 있는 데이터를 검색한다. 커밋되지 않은 데이터를 리드하기 때문에 더티리드 후 더티페이지가 롤백이 되면 잘못된 데이터를 읽어온 경우가 되어버린다.
- 아래 예시에서 트랜잭션 A가 트랜잭션을 끝마치지 못하고 롤백한다면 트랜잭션 B는 무효가 된 값을 읽고 처리한다.
NON-REPEATABLE READ - 같은 트랜잭션 내에서 같은 값을 조회할 때 다른 값이 조회된다.
- 같은 트랜잭션 내에서 READ시 값이 다르게 나오는 데이터 불일치 문제
- 하나의 트랜잭션에서 같은 쿼리를 두번 이상 수행할 때, 똑같은 쿼리임에도 다른 결과를 볼 수 있게 되는 현상
- 트랜잭션 중 데이터가 변경되면 문제가 발생할 수 있다.
Phantom Read - 없던 데이터가 생기거나, 있던 데이터가 사라지는 것을 말한다.
- 한 트랜잭션내에서 동일한 쿼리를 두 번 수행했는데, 첫 번째 쿼리에서 존재하지 않던 유령(Phantom) 레코드가 두 번째 쿼리에서 나타나는 현상
- NON-REPREATABLE READ의 한 종류
- 하나의 트랜잭셩네서 일정 범위의 레코드를 두번이상 읽을 때, 똑같은 쿼리임에도 첫번째 쿼리에서 없던 레코드가 두번째 쿼리에서 나타나는 현상
트랜잭션 전파 타입
트랜잭션을 시작하거나 기존 트랜잭션에 참여하는 방법을 결정하는 속성.
- REQUIRED
- 현재 진행중인 트랜잭션이 존재하면 해당 트랜잭션을 사용한다.
- 존재하지 않으면 새로운 트랜잭션을 생성한다.
- 두 메서드가 하나의 트랜잭션으로 실행되기 때문에 어느 메서드에서 문제가 발생해도 실행했던 모든 쿼리가 롤백된다.
- MANDATORY
- REQUIRED와 달리 진행 중인 트랜잭션이 존재하지 않을 경우 예외가 발생한다.
- REQUIRES_NEW
- 항상 새로운 트랜잭션을 시작한다.
- 진행 중인 트랜잭션이 존재하면 기존 트랜잭션을 일시 중지하고 새로운 트랜잭션을 시작한다.
- 새로운 트랜잭션이 종료된 뒤에 기존 트랜잭션이 계속된다.
- SUPPORTS
- 진행중인 트랜잭션이 있다면 트랜잭션을 사용한다.
- 진행중인 트랜잭션이 없다면 트랜잭션 없이 메서드가 정상동작한다.
- NOT_SUPPORTED
- SUPPORT와 달리 진행 중인 트랜잭션이 존재할 경우 메서드가 실행되는 동안 트랜잭션을 일시 중지 되고 메서드 실행이 종료된 후에 트랜잭션을 계속 진행한다.
- 트랜잭션을 사용하지 않는 설정
- NEVER
- 메서드가 트랜잭션을 필요로 하지 않는다.
- 만약 진행 중인 트랜잭션이 존재하면 예외 발생
- NESTED
- 진행 중인 트랜잭션이 존재하면 그 안에 새로운 트랜잭션을 만드는 설정
- 중첩된 트랜잭션 2는 부모인 트랜잭션1의 커밋, 롤백에는 영향을 받는다.
- 트랜잭션2의 커밋 롤백에는 트랜잭션1이 영향을 받지 않는다.
참조
'하루한개 > 우아한 테크코스-10분테코톡' 카테고리의 다른 글
멍토의 Non-Blocking/Blocking 과 Async/Sync (0) | 2023.04.23 |
---|---|
디디의 Redis (0) | 2023.03.21 |
데이터베이스 락 (Database Lock, DB Lock) (0) | 2022.09.03 |
정규표현식 and With Java (0) | 2022.08.31 |
캐시(Cache), 브라우저 캐시, Spring Boot Cache (0) | 2022.08.21 |