서론
Spring을 사용하여 개발하다 보면 service 단에서 @transaction 처리를 해줍니다. 항상 사용하면서 대충 느낌적으로 트랜잭션이 뭔지는 알겠으나 정확하게 입 밖으로 정리돼서 나오지가 않아 이번 기회에 정리를 하게 되었습니다.
트랜잭션(transaction)
트랜잭션이란 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 논리적 단위입니다. 데이터 베이스의 상태를 변화시킨다는 말은 SELECT, INSERT, UPDATE, DELETE 등과 같은 조작어를 사용하는 행동을 의미합니다.
이런 트랜잭션은 상황에 따라 여러 개가 만들어 질 수 있고, 그 각각의 트랜잭션들은 상황에 따라 Commit(저장) 되거나 Rollback(철회) 될 수 있습니다.
- 커밋(Commit): 모든 부분작업이 정상적으로 완료하면 이 변경사항을 한꺼번에 DB에 반영한다.
- 롤백(Rollback): 부분 작업이 실패하면 트랜잭션 실행 전으로 되돌린다.
트랜잭션의 사용 이유
ATM으로 계좌이체를 한다고 가정해 봅시다.
- A 은행에서 출금하여 B은행으로 송금하려고 한다.
- 송금 중, 알 수 없는 오류가 발생하여 A은행 계좌에서 돈은 빠져나갔지만 B은행의 계좌에 입금되지 않았다.
- 이와 같은 상황을 막기 위해 거래가 성공적으로 모두 끝나야 이를 완전한 거래로 승인하고, 거래 도중 뭔가 오류가 발생했을 때는 이 거래를 처음부터 없었던 거래로 완전히 되돌린다.
이렇게 거래의 안전성을 확보하는 방법이 트랜잭션입니다. 데이터베이스에서는 테이블로부터 데이터를 읽어 온 후 다른 테이블에 데이터를 입력하거나 갱신, 삭제하는데 처리 도중 오류가 발생하면 Rollback 되고, 모든 처리 과정이 성공적으로 수행되었을 경우에 최종적으로 Commit 됩니다.
즉, 트랜잭션의 의미는 아래와 같습니다.
- 트랜잭션은 데이터베이스 시스템에서 병행 제어 및 회복 작업 시 처리되는 작업의 논리적 단위이다.
- 사용자가 시스템에 대한 서비스 요구 시 시스템이 응답하기 위한 상태 변환 과정의 작업단위이다.
- 하나의 트랜잭션은 Commit 되거나 Rollback 된다.
트랜잭션의 특징
트랜잭션에는 4가지의 특징(Atomicity, Consitency, Isolation, Durability)이 있습니다. 4가지의 특징의 앞 글 자만 따서 ACID라고도 불립니다.
1. 원자성(Atomicity)
- 트랜잭션의 작업이 부분적으로 실행되거나 중단되지 않는 것을 보장한다.
- 즉, 트랜잭션이 DB에 모두 반영되거나 혹은 전혀 반영되지 않아야 합니다.(All or Nothing)
트랜잭션에서 원자성은 수행하고 있는 트랜잭션에 의해 변경된 내역을 유지하면서, 이전에 commit 된 상태를 임시 영역에 따로 저장함으로써 보장합니다. 만약 현재 수행하고 있는 트랜잭션에서 오류가 발생하면 현재 내역을 날려버리고 임시 영역에 저장했던 상태로 rollback 합니다.
이전 데이터들이 임시로 저장되는 영역을 롤백 세그먼트(rollback segment)라고 하며, 롤백 세그먼트는 수정되기 전의 파일, 블록 ID같은 블럭 정보 및 데이터를 저장합니다. 현재 수행하고 있는 트랜잭션에 의해 새롭게 변경되는 내역을 데이터베이스 테이블이라고 합니다.
여기서 오류가 발생하면 rollback을 하는데, 트랜잭션의 길이가 엄청나게 길다면 어떻게 될까요? 확실하게 오류가 발생하지 않은 부분도 다시 처음부터 작업을 수행해야 합니다.
따라서 이러한 부분을 해결하기 확실한 부분에 대해서는 rollback 되지 않도록 중간 저장 지점인 save point를 지정하여 해결할 수 있습니다.
save point
- 일반적으로 Rollback을 명시하면 INSERT, DELETE, UPDATE 등의 작업 전체가 취소된다.
- SAVEPOINT를 사용하면 전체가 아닌 특정 부분에서 트랜잭션을 취소시킬 수 있다.
- 취소하려는 지점을 SAVEPOINT로 명시한 뒤 ROLLBACK TO SAVEPOINTNAME; 을 실행하면 지정한 해당 SAVEPOINT 지점까지 처리한 작업이 ROLLBACK 됩니다.
2. 일관성(Constency)
- 트랜잭션의 작업 처리 결과는 항상 일관성이 있어야 한다.
- 예를 들어, 작성 테이블의 본문 내용의 글자 제한이 255글자이고, 트랜잭션이 일어나면 글자 제한 조건을 만족해야만 트랜잭션이 수행되고 위반한다면 거부해야 합니다.
- 즉, 트랜잭션 수행 전, 후에 데이터 모델의 모든 제약 조건(기본키, 외래 키, 도메인, 도메인 제약조건 등)을 만족해야 합니다.
트랜잭션에서 일관성 보장은 어떤 이벤트와 조건이 발생했을 때, 트리거(Trigger)를 통해 보장합니다.
트리거(Trigger)
트리거는 특정 테이블에 INSERT, DELETE, UPDATE 같은 DML 문이 수행되었을 때, 데이터베이스에서 자동으로 동작하도록 작성된 프로그램입니다. 사용자가 직접 호출하는 형태가 아니라, 데이터베이스에서 자동적으로 호출하는 것이 특징입니다.
따라서 트리거를 통해서 데이터베이스의 일관성이 보장될 수 있는데, 예를 들어 한쪽 데이터베이스의 테이블에 정보의 수정이 일어났을 경우 다른 쪽 테이블에도 함께 정보가 수정될 수 있도록 명시적으로 자동 업데이트를 하는 명령 등을 구성하게 됩니다.
3. 격리성, 고립성(Isolation)
- 트랜잭션 수행 시 다른 트랜잭션의 작업이 끼어들지 못하도록 보장해야 한다.
- 즉, 둘 이상의 트랜잭션이 동시에 병행(parallelism) 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연상에 끼어들 수 없습니다.
격리성을 보장하기 위해서는 Lock & Unlock 기법을 사용합니다.
Lock & Unlock
데이터를 읽거나 쓰기 작업 중일 때는 해당 영역에 Lock을 걸어서 다른 트랜잭션이 접근하지 못하도록 하고, 먼저 들어온 트랜잭션의 요청이 끝나면 Unlock 하여 다른 트랜잭션이 처리될 수 있도록 허용하는 방식을 통해 격리성/고립성을 보장할 수 있습니다.
만약 Lock과 Unlock을 잘 못 사용하게 되는 경우 어떠한 트랜잭션도 수행될 수 없는 데드락(Deadlock) 상태에 빠질 수 있습니다.
4. 지속성, 영속성(Durability)
- 성공적으로 수행된 트랜잭션은 영원히 반영되어야 한다.
- 즉, 트랜잭션이 성공적으로 종료되어 Commit 연산을 실행했다면 해당 데이터는 데이터베이스에 영원히 반영이 되어야 합니다.
'ETC' 카테고리의 다른 글
당신은 트랜잭션에 대해 얼마나 알고 있는가 (4) | 2023.06.06 |
---|---|
이진트리 탐색 운행법 (0) | 2022.06.21 |
[OS] (동기/비동기) 와 (블럭/논블록의) 차이 (0) | 2022.04.11 |
[python] 클래스 변수와 __dict__ (0) | 2021.12.14 |
[python] Broadcasting(브로드캐스팅) (0) | 2021.12.14 |
[python] 클래스의 특별한 메서드 (0) | 2021.12.12 |
댓글