Transaction 이란
여러 쿼리를 논리적으로 하나의 작업 단위로 묶는 것을 의미한다.
예로 계좌 이체가 있다. 적어도 보내는 사람과 받는 사람의 계좌는 업데이트가 되어야 한다.
이 두 번의 DB 작업을 논리적으로 하나의 작업으로 묶는 것이다.
Transaction 성질
원자성 : 트랜잭션의 쿼리 결과들이 모두 반영되거나, 모두 반영되지 않아야 한다.
일관성 : 트랜잭션은 일관성 있는 데이터베이스 상태를 유지한다.
격리성 : 동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리해야 한다.
지속성 : 트랜잭션을 성공적으로 마치면 결과가 항상 저장되어야 한다.
Spring의 @Transactional
Mybatis, hiberbate, jdbcTemplate 디비 접근 기술에 따라 트랜잭션을 적용하는 코드가 다 제각각이다. 그래서 스프링에선 @Transactional이란 추상 서비스를 제공한다. @Transational은 클래스와 메서드 단위에 적용이 가능하며 어노테이션을 붙이게 되면 Proxy를 만들게 된다. 즉 PSA와 AOP인 셈이다.
@Transactional의 속성
[Isolation (트랜잭션 격리)]
트랜잭션에서 일관성 없는 데이터 허용 수준을 설정한다
▶ default
- DB의 Isolation Level을 따른다.
▶ Read_Uncommited (lv.0)
- 가장 낮은 격리 수준으로 커밋되지 않는 트랜잭션의 데이터 읽기를 허용한다.
- 동기 작업이 없기 때문에 속도가 빠르다.
- Dirty Read, Non-Repeatable Read, Phantom Read 이슈로 데이터 불일치 위험이 있다.
▶ Read_Committed(lv.1)
- 커밋이 완료된 트랜잭션의 변경사항만 다른 트랜잭션에서 조회 가능하다.
- 트랜잭션이 값을 변경하고 커밋하는 시점마다 다른 트랜잭션에서 데이터 조회 시 불일치가 나타날 수 있다. (Non-Repeatable Read)
- Drity Read 방지하지만 Non-Repeatable Read, Phantom Read 이슈가 있다.
▶ REPEATABLE_READ (level 2)
- 트랜잭션 범위 내에서 조회한 내용이 항상 동일함을 보장한다.
- 하지만 새로 추가되거나 삭제된 데이터를 제한하지 않는다. (Phantom Read)
- Drity Read, Non-Repeatable Read 방지하지만 Phantom Read 이슈가 있다.
▶ SERIALIZABLE (level 3)
- 가장 강력한 트랜잭션 격리 수준으로 한 트랜잭션에서 사용하는 데이터를 다른 트랜잭션에서 접근을 막는다.
- Drity Read, Non-Repeatable Read, Phantom Read 방지한다.
레벨이 높아질수록 데이터 무결성은 유지하나 그만큼 성능에 불리하다.
상황에 맞게 적절한 격리 레벨을 사용하는 것이 중요하겠다.
[propagation (전파 옵션) ]
트랜잭션을 생성 및 호출에 대한 설정이다.
부모의 트랜잭션을 그대로 사용하거나 새로운 트랜잭션을 생성할 수 있다.
▶ REQUIRED
- 부모 트랜잭션이 존재한다면 부모 트랜잭션의 속성을 따르고, 그렇지 않다면 새로운 트랜잭션을 생성한다.
▶ SUPPORTS
- 부모 트랜잭션이 존재한다면 부모 트랜잭션의 속성을 따르고, 그렇지 없다면 새로 트랜잭션을 생성하지 않는다.
▶ REQUIRES_NEW
- 부모 트랜잭션 유무와 상관없이 항상 새로운 트랜잭션을 생성한다.
- 부모 트랜잭션이 존재한다면 새로 만든 트랜잭션 작업이 끝날 때까지 보류시킨다.
▶ MANDATORY
- 부모 트랜잭션을 따르며, 부모 트랜잭션이 존재하지 않다면 예외를 발생시킨다.
▶ NOT_SUPPORTED
- 트랜잭션을 사용하지 않고, 부모 트랜잭션이 있다면 보류시킨다.
▶ NEVER
- 트랜잭션을 절대 사용하지 않는다.
- 부모 트랜잭션이 존재한다면 예외를 발생시킨다.
▶ NESTED
- REQUIRES_NEW처럼 새로운 트랜잭션을 만든다.
- 새로운 트랜잭션은 부모 트랜잭션의 커밋과 롤백에 영향을 받는다. 하지만 새로운 트랜잭션의 커밋과 롤백은 부모 트랜잭션에 영향을 주지 않는다.
[readOnly 속성]
트랜잭션을 읽기 전용으로 설정한다.
Insert, Update, Delete 작업이 진행되면 예외가 발생한다.
읽기 전용 트랜잭션의 성능은 기본 트랜잭션보다 성능이 좋다.
[timeout 속성 ]
지정한 시간 내에 트랜잭션 처리를 수행하지 못할 경우 Rollback을 수행한다.
기본값은 -1이며 timeout을 사용하지 않는다는 의미이다.
[트랜잭션 롤백 예외]
▶ noRollbackFor
특정 예외 발생 시 rollback하지 않는다.
▶ rollbackFor
특정 예외 발생 시 rollback 한다.
Checked Exception 같은 경우 예외 처리를 강제하기 때문에 스프링에선 하나의 로직이라 보고 롤백시키지 않는다. UnChecked Exception은 예외를 강제하지 않는 예상치 못한 예외로 보기 때문에 롤백시킨다.
'Spring' 카테고리의 다른 글
Spring Data Jpa의 N+1 문제 (0) | 2022.02.07 |
---|---|
JDK Dynamic Proxy와 CGLIB (0) | 2021.12.07 |
Spring AOP (0) | 2021.12.02 |
Spring Boot에 Redis Cache 적용해보기 (0) | 2021.11.25 |
Spring JPA Specification을 사용해 유연하게 조회 API 만들기 (3) | 2021.11.08 |
댓글