2022. 8. 30. 18:14ㆍSpring
트랜잭션이란?
DBMS에서 기능을 수행하기 위한 작업 혹은 상호작용의 단위이다.
즉 여러개의 쿼리를 하나로 묶는 단위이다
begin과 commit을 자동으로 수행해주기도 하며 예외 발생시 rollback 처리를 자동으로 수행한다.
먼저 트랜잭션에 대하여 간단하게 알아보자.
트랜잭션의 성질 (ACID)
1. 원자성
- 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 한다.
2. 일관성
- 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다.
- 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다.
- 무결성: 데이터의 정확성, 일관성, 유효성을 유지하는 것
- 무결성의 종류
- 개체 무결성: 기본키로 선택된 필드는 빈 값을 허용하지 않는다.
- 참조 무결성: 서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 한다.
- 고유 무결성: 특정 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 그 속성 값은 모두 고유한 값을 가진다.
- NULL 무결성: 특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우 그 속성 값은 NULL이 될 수 없다
3. 격리성 (독립성)
- 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다.
- 예를 들어 동시에 같은 데이터를 수정하지 못하도록 해야한다 ( DB Lock )
- 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation level)을 선택 할 수 있다.
4. 지속성
- 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템이 문제가 발생해도 데이터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 한다.
트랜잭션 격리 수준 (Isolation)
READ_UNCOMMITED LEVEL 0
- 가장 낮은 격리 수준
- 트랜잭션이 커밋되기 이전에 다릍 트랜잭션에 노출되는 문제가 있지만 가장 빠름
- 이는 데이터 무결성을 위해 되도록이면 사용하지 않아야 하나
몇몇 행이 제대로 조회되지 않더라도 괜찮은 거대한 양의 데이터를 어림잡아 집계하는데 사용하면 좋다.
이를 더티 리드라고도 한다
READ_COMMITED LEVEL 1
- 가장 많이 사용 되는 격리 수준이며 My SQL, PostgresSQL 등 여러 DBMS에서 기본값으로 설정되어 있다.
- 다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없다. 즉, 커밋 완료된 데이터에 대해서만 조회를 허용
- 하지만 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수 있다.
- 예를 들어 트랜잭션 A가 수정한 행을 트랜잭션 B가 수정할 수도 있다.
- 이 때문에 트랜잭션 A가 같은 행을 다시 읽을 때 다른 내용이 발견될 수 있다.
이를 반복 가능하지 않은 조회라고 한다.
REPEATEBALE_READ LEVEL 2
- 하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아주지만
새로운 행을 추가하는 것은 막지 않는다. - 때문에 이후 추가된 행이 발견될 수도 있다 이를 팬텀리드라고 한다.
SERIALIZABLE LEVEL 3
- 트랜잭션을 순차적으로 진행
- 여러 트랜잭션이 동시에 같은 행에 접근할 수 없다.
- 매우 엄격한 수준으로 해당 행에 대해 격리 시키고 이후 트랜잭션이 이 행에 대해 일어난다면 기다려야 한다.
- 때문에 교착 상태가 일어날 확률도 많고 가장 성능이 떨어지는 격리 수준
단순히 조건으로 보면 레벨이 높을 수록 좋아 보이지만
각 격리 수준마다의 장잔점이 있다.
때문에 무슨 로직이냐에 따라서 고민하고 수준을 지정해야한다.
Spring Transaction
@Transactional
Spring에서 사용되는 어노테이션으로.
메소드, 클래스, 인터페이스에 추가하여 사용 할 수 있다.
이를 선언적 트랜잭션이라고 하며
프록시 객체가 생성되어 자동으로 커밋과 롤백을 진행해준다.
Annotaion Option
- isoloation
- DB 데이터허용 수준(격리 수준)을 설정한다.
- 위에서와 같은 READ_UNCOMMITED, READ_COMMITED, REPEATEABLE_READ, SERIALIZABLE을 설정 할 수 있다.
- Default 값은 사용 하는 DBMS의 기본 격리 수준을 따른다.
- propagation
- 트랜잭션 동작 도중 다른 트랜잭션이 호출될 경우 어떻게 할지 지정하는 옵션이다.
- 트랜잭션 전파 라고도 한다.
- REQUIRED
- 이미 진행중인 트랜잭션이 있으면 해당 트랜잭션의 속성을 따른다. 아니라면 새로운 트랜잭션을 생성한다.
- REQUIRES_NEW
- 항상 새로운 트랜잭션을 생성하낟. 이미 진행되고 있는 트랜잭션이 있다면 보류 후 해당 트랜잭션을 먼저 작업한다.
- SUPPORT
- 이미 진행중인 트랜잭션이 있으면 해당 트랜잭션의 속성을 따르고, 없다면 트랜잭션을 설정하지 않는다.
- NOT_SUPPORT
- 이미 진행중인 트랜잭션이 있다면 보류하고, 트랜잭션 없이 작업을 수행한다.
- NEVER
- 트랜잭션이 진행중이지 않을때 수행한다. 있다면 Exception을 발생 시킨다.
- NESTED
- 진행중인 트랜잭션이 있다면 중첩 트랜잭션이 실행되며, 존재하지 않으면 REQUIRED와 동일하다.
- MANDATORY
- 이미 진행중인 트랜잭션이 있어야만 작업이 수행된다. 없다면 Exception을 발생 시킨다.
- REQUIRED
- noRollbackFor
- 특정 예외 집어 해당 예외에 한해서는 rollback 하지 않는다.
- rollbackFor
- 특정 예외 발생 시 rollback 한다.
- @Trasactional은 모든 예외에 대해 롤백을 수행하지 않는다.
(Unchecked Exception or Error 만을 rollback 한다) - 때문에 모든 예외에 대해 롤백을 처리하고 싶은 경우
@Transactional(rollbackFor= Exception.class)로 지정해주어야 한다.
- timeout
- 지정 시간내에 메소드의 수행이 완료되지 않으면 rollback 한다.
- readOnly
- 트랜잭션을 읽기 전용으로 설정한다.
- 읽기 전용으로 설정시 성능이 조금이나마 상승한다.
- readyOnly가 true인 트랜잭션에서 insert, update, delete가 실행되면 예외가 발생한다.
옵션 설정법
스프링은 오랫동안 사용된 만큼 서버관리에 대한 노하우나, 꿀 기능들이 스프링 내부에 많이 녹아들어 있다.
허나 이러한 점을 모른다면 매우 고생할 뿐만 아니라.
어떠한 부분에서 문제가 되는지도 파악이 안될 경우가 있다.
이를 방지하기위하여 미리미리 공부를 해놓도록 하자.
'Spring' 카테고리의 다른 글
Hello Spring Batch!, SpringBatch 시작하기 (0) | 2022.09.09 |
---|---|
WebFlux + MongoDB + SSE 로 채팅만들기 (0) | 2022.09.04 |
우당탕탕 Nginx 적용기 ( 근데 이제 Actions를 곁들인.. ) (0) | 2022.08.18 |
Spring의 JDBC, SQLMAPPER, ORM (0) | 2022.05.12 |
Web Server 와 WAS (0) | 2022.05.09 |