트랜잭션(Transaction)은 데이터베이스에서 사용되는 개념으로, 하나 이상의 데이터베이스 작업(쿼리)을 묶어서 논리적으로 단일 작업 단위로 처리하는 것을 의미한다. 트랜잭션은 데이터베이스 시스템에서 데이터의 무결성을 보장하고, 데이터베이스 작업을 안전하게 수행하기 위해 사용된다.
예제를 통해 개념을 더 쉽게 이해해보자.
J와 H가 있다. J가 H에게 20만원을 이체한다면 각자의 계좌는 어떻게 변경돼야 할까?
초기 상태는 J는 100만원 H는 200만원을 가지고 있다.
J의 계좌에서 20만원이 빠지고 80만원이 남고 H의 계좌에는 20만원이 들어오고 220만원이 남게된다.
이것을 SQL문으로 표현한다면 아래와 같다.
account라는 테이블에 J에 대해서 balance에서 20만원을 빼주고 새로운 balance로 업데이트 해준다.
동일하게 account라는 테이블에 H에 대해서 balance에 20만원을 더해주고 새로운 balance로 업데이트 해준다.
이 두 개의 작업이 모두 성공해야 이체라는 작업이 성공하는 것이다. 만약 둘중 하나라도 실패한다면 20만원이 증발하거나 갑자기 20만원이 생겨버리는 오류가 발생하게 된다.
이 작업은 둘 다 정상 처리돼야만 성공하는 단일 작업이다. 이 단일 작업을 데이터베이스에서는 트랜잭션이라고 한다.
트랜잭션의 개념은 다음과 같다.
단일한 논리적인 작업 단위(a single logical unit of work)
논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 없게 만든 것이 transaction이다.
transaction의 SQL문들 중에 일부만 성공해서 DB에 반영되는 일은 일어나지 않는다.
트랜잭션의 특징은 다음과 같다.
원자성(Atomicity): 트랜잭션은 원자적인 작업 단위로 간주된다. 즉, 모든 데이터베이스 작업이 성공하거나 실패해야 한다. 하나의 작업이라도 실패하면 이전에 수행된 작업들을 모두 롤백하여 데이터베이스를 이전 상태로 되돌려야 한다.
일관성(Consistency): 트랜잭션이 실행 전과 후에 데이터베이스는 일관된 상태여야 한다. 트랜잭션이 완료된 후에도 데이터베이스 제약 조건을 준수해야 한다.
고립성(Isolation): 여러 개의 트랜잭션이 동시에 실행될 때 서로 영향을 미치지 않고, 각각 독립적으로 실행되는 것처럼 보장해야 한다. 다른 트랜잭션의 작업이 현재 실행 중인 트랜잭션에 영향을 미치지 않아야 한다.
지속성(Durability): 트랜잭션이 성공적으로 완료된 후에는 그 결과가 영구적으로 저장되어야 한다. 시스템 장애나 중단이 발생해도 트랜잭션의 결과는 손실되지 않아야 한다.
위 4가지 특징을 통틀어 ACID라고 하고 데이터베이스 트랜잭션은 ACID라는 특성을 가지고 있다고 한다.
ACID는 주식거래, 금융업에서 중점적으로 사용된다. 관계형 데이터베이스를 사용하면 데이터베이스와 상호작용하는 방식을 정확하게 규정할 수 있기 때문에, 데이터베이스에서 데이터를 처리할 때 발생할 수 있는 예외적인 상황을 줄이고, 데이터베이스의 무결성을 보호할 수 있다.
위에서 설명했던 예제를 코드를 통해서 확인해보자.
select * from account;
+----+---------+
| id | balance |
+----+---------+
| J | 1000000 |
| H | 2000000 |
+----+---------+
account라는 테이블의 현재 상태다.
이제 J가 H에게 20만원을 송금하는 작업을 수행해보자.
START TRANsACTION; // 트랜잭션을 시작한다.
UPDATE account SET balance = balance - 200000 WHERE id = "J"; // J의 계좌에서 20만원을 이체한다.
UPDATE account SET balance = balance + 200000 WHERE id = "H"; // H의 계좌에 20만원을 입금한다.
COMMIT; // 지금까지 작업한 내용을 DB에 영구적으로 저장한다.(트랜잭션 종료)
이제 작업이 정상적으로 처리됬는지 보자.
select * from account;
+----+---------+
| id | balance |
+----+---------+
| J | 800000 |
| H | 2200000 |
+----+---------+
정상적으로 작동한 것을 확인할 수 있다.
만약 중간에 작업을 취소하고 싶다면,
ROLLBACK // 지금까지 작업들을 모두 취소하고 트랜잭션 이전 상태로 되돌린다.(트랜잭션 종료)
ROLLBACK
을 사용해서 되돌릴 수 있다.
스프링부트 책을 보다가 트랜잭션이 뭔지 궁금해서 찾아봤다.
트랜잭션은 주로 데이터베이스에서 데이터를 안전하게 조작하고 일관성을 유지하는 데 사용된다. 위의 예제처럼 은행 거래에서 돈을 이체하는 경우, 이체 작업과 잔액 업데이트 작업을 하나의 트랜잭션으로 묶어야 한다. 이렇게 하면 이체 작업이 실패할 경우 돈이 누락되거나 잘못된 잔액이 표시되는 문제를 방지할 수 있다.
프로그래밍에서도 트랜잭션 개념을 사용할 수 있으며, 예를 들어 데이터베이스 이외의 작업에서도 파일 조작, 네트워크 통신, 메시지 큐 등에서 트랜잭션과 유사한 개념을 적용할 수 있다고 한다.
추후에 데이터베이스를 사용할 기회가 있다면 다시 찾아봐도 좋은 영상인 것 같다.
참고
데이터베이스 트랜잭션(transaction)을 아십니까? 그리고 트랜잭션의 매우 중요한 속성들인 ACID를 아십니까? 모르신다면 들렀다 가시지요
트랜잭션(Transaction)이란?