Transaction
<em>"트랜잭션을 설명해보세요."</em> <em>질문에</em> <em>무슨 대답을 해야할까요..</em>
<br/>
K사 면접때 소스코드를 보신 면접관님이 던지신 질문입니다. 불합격 :'(
트랙잭션을 설명하라하셔서, 틀린답은 아니지만 ACID 성질을 말씀드렸는데 교과서적인 대답에 내가 다 민망했던 기억이.. ?
<br/>
모른걸 또 모를 수 없으니, 공부를 하며 내용을 정리해봅니다.
<br/>
트랜잭션은 한번에 처리 해야할 수행 작업단위입니다.
<br/>
즉 한번에 처리되거나, 아예 처리되지 않거나.
<br/>
ACID 성질을 가지는데..
-
A - 원자성 : 모두 완료되거나 또는 모두 취소 되어야 한다.
-
C - 일관성 : 트랜잭션이 작용 전/후 일관된 DB 상태를 유지하여야 한다.
-
I - 고립성 : 트랜잭션 수행시 다른 트랜잭션이 간섭하지 않아야한다.
-
D - 지속성 : 트랜잭션 수행 완료, 트랜잭션은 영원히 반영되어야 한다.
<br/>
<br/>
일관성은 트랜잭션 전/후 기본키 외래키 같은 제약조건이 일관된 DB상태를 가져야 함을 말합니다.
예를 들어, A클래스에서 외래키로 B클래스의 기본키를 참조한다고 한다면, 트랜잭션 수행 중 B클래스의 키값 변경에 A클래스 외래키에 반영되어야 합니다. 이와 같이 트랜잭션 종료후 일관된 DB상태를 가져야 함을 말합니다.
<br/>
고립성은 A트랜잭션이 수행할때 B트랜잭션이 간섭하여 데이터의 무결성을 깨트리지 못하도록하는 것을 말합니다.
A트랜잭션이 수행중에 값을 50으로 바꾸고, 이 와중에 B트랜잭션이 값을 100으로 바꾸지 못하도록 하여야 합니다.
<br/>
<hr/>
<br/>
그럼 여러 트랜잭션이 경쟁하면 어떤 문제가 발생할까요?
여러개의 트랜잭션이 동시에 수행되어, 레코드를 컨트롤한다면 어떻게 될까요?
다음과 같은 3가지 문제점이 발생합니다.
<br/>
Dirty Read
예를 들어, A 트랜잭션이 X레코드값을 100으로 바꾸고 커밋을 하지 않았지만,
B트랜잭션이 X레코드 값을 참조하여 100값을 읽는 상황입니다.
<br/>
Non-Repeatable Read
A트랜잭션이 수행중 X레코드값을 100을 읽었습니다.
이 와중에 B트랜잭션이 X레코드값을 1로 바꾸고 커밋하였습니다.
A트랜잭션이 수행중 다시 X레코드값을 읽었습니다. 읽어온 값은 1 입니다.
A트랜잭션 입장에서는 엥 100이었는데, 다시 읽었더니 1이네?
<br/>
Phantom Read
A트랜잭션이 수행 중 어떤 조건의 쿼리에 X,Y,Z 값을 가져왔습니다.
이 와중에 B트랜잭션이 Y, Z값을 삭제하고 커밋하였습니다.
A트랜잭션이 수행 중 동일한 조건의 쿼리로 값을 가져왔스니다. 읽어온 값은 X 뿐 입니다.
A트랜잭션 입장에서는 엥 처음에 X,Y,Z 더니,, 다시 읽으니까 X네?
<br/>
<hr/>
<br/>
이렇듯, 발생하는 문제에 대한 격리(고립) 처리를 가져야 합니다.
4가지의 격리 레벨로 처리하는데, 레벨이 높을수록 성능이 저하되기 때문에,
**따라서 개발자는 적절한 수준의 레벨을 선택하여야 합니다. **
어느 정도 성능에 어떻게 선택해야하는지는 흠 ?
<br/>
<br/>
Level 0, Read Uncommited
다른 트랜잭션이 커밋하지 않은 레코드에 접근 가능합니다.
모든 문제에 대해 예방할 수 없습니다.
<br/>
Level 1, Read commited
다른 트랜잭션이 커밋한 레코드에만 접근 가능합니다.
따라서 Dirty Read는 예방 할 수 있습니다.
<br/>
Level2 - Repeatable Read
특정 레코드를 읽은 트랙잭션이 있을때, 그 레코드의 수정/삭제 하는 것을 방지합니다.
Level 1에 더해, Repeatable Read를 예방 할 수 있습니다.
<br/>
Level3 - Serializble Read
어떤 트랜잭션이 특정 조건의 쿼리로 레코드들을 조회할때, 그 범위의 레코드에 대해서 조회/생성/수정/삭제 하는 것을 방지합니다.
Level2에 더해, Panthom Read를 예방 할 수 있습니다.
<br/>
<br/>
Spring의 트랜잭션은, 각 격리레벨을 설정할 수 있습니다.
그럼 이제 스프링을 공부해야겠어요...?
<br/>
<br/>
참고
<a href="https://victorydntmd.tistory.com/129" target="_blank">https://victorydntmd.tistory.com/129</a>
<a href="https://preamtree.tistory.com/154" target="_blank">https://preamtree.tistory.com/154</a>
<br/>