트랜잭션(Transaction)
: 데이터베이스를 대상으로 수행되는 여러 가지 처리를 하나로 모은 것
SQL은 한 문장씩 실행할 수 있는데, 연속해서 여러 개의 데이터를 추가하거나 갱신해야 할 경우에는 하나의 액션으로 실행되도록 일련의 처리를 묶을 수 있다.
은행 계좌 예시
: A 계좌에서 B계좌로 10만 원을 송금
- A 계좌의 예금을 마이너스 10만 원으로 한다
- B 계좌의 예금을 플러스 10만 원으로 한다
→ 2가지 처리를 동시에 실행시킬 필요가 있다.
그런데 만약 A 계좌의 처리가 완료된 직후에 시스템에 문제가 발생하여 B 계좌에 대한 처리가 실행되지 않으면 B 계좌에 송금액이 반영되지 않게 되어버리는 일이 발생한다.
이러한 처리들을 트랜잭션으로 일괄 완료시킴으로써 데이터가 맞지 않게 되는 문제의 발생을 막을 수 있다.
처리가 도중에 중단됨으로써 발생하는 데이터의 부정합을 트랜잭션으로 방지할 수 있다.
원자성(atomaticity)
: 트랜잭션에 포함된 처리는 "모두 실행된다" 이거나 "모두 실행되지 않는다" 중 하나가 된다.
일관성(consistency)
: 미리 설정된 조건을 충족하고 데이터의 정합성을 보충한다.
독립성(independency)
: 처리 도중 경과가 은폐되고 외부에서는 결과만 볼 수 있다. 처리 실행 도중의 상태에서는 다른 처리에 영향을 주지 않는다.
영속성(permanency)
: 트랜잭션이 완료되면 그 결과가 손실되는 일은 없다.
- 트랜잭션을 사용할 경우 SQL 문장을 실행하는 과정에서는 아직 데이터베이스에 결과가 반영되지 않는다.
- 마지막으로 커밋을 실시하면, 그때에야 비로소 처음으로 변경 내용이 적용된다.
- 은행 계좌 예시
- A계좌에서 B계좌로 10만 원을 송금할 때, 데이터베이스상에서는 트랜잭션을 이용해 "A계좌의 예금을 마이너스 10만 원으로 한다."
- 두 가지 처리를 실행하고 마지막으로 커밋을 한다.
이 때 중간 경과는 외부에서 보이지 않으므로 다른 처리에서 명령어 실행 중인 값은 보이지 않으며
A 계좌의 값 갱신 직후에 다른 처리가 유입되는 일은 없다.
B 계좌의 값 갱신도 하고 마지막으로 커밋을 실행해야 비로소 데이터베이스에 결과가 반영되어 다른 처리들이 데이터베이스에 반영된 그 값을 읽어낼 수 있게 된다.
START TRANSACTION;
을 실행하고, -> 이 시점에서는 아직 데이터베이스에 결과 반영X
COMMIT;
명령어를 실행-> 커밋 수행, 데이터베이스에 변경 내용 적용 상태 커밋을 하기 전에는 트랜잭션 내에서 명령어 실행은 실행 중인 값은 다른 처리에서는 보이지 않는다.
- 프로그램에서 버그나 네트워크 장애로 인해 데이터베이스에 접속할 수 없게 되는 등 여러 가지 예상치 못한 문제가 발생한다.
- 그럴 때 트랜잭션 내의 처리를 도중에 중단해 버리면 데이터의 정합성을 확보할 수 없게 되는 경우도 있다.
트랜잭션 내의 처리를 취소하고 무결성이 유지된 상태까지 복구한다.
(트랜잭션 개시시점 상태까지 되돌아간다)은행 계좌 예시 (정상적인 경우)
- A 계좌에서 B 계좌로 10만 원을 송금할 때는 정상적인 경우 데이터베이스상에서는 트랜잭션을 이용하여 A로 된 예금을 마이너스 10만 원으로 한다
- B로 된 예금을 플러스 10만 원으로 한다와 같은 두 가지 처리를 하고,
- 마지막에 커밋을 하는 흐름
A 계좌의 값을 갱신한 직후 문제가 발생하여 처리를 계속 할 수 없게 되어버린 경우,
- 롤백을 수행하여 트랜잭션 시작 시점 상태까지 되돌아간다.
트랜잭션 내 처리는 아무것도 이루어지지 않은 상태이므로 데이터베이스 상에서 변화는 없다.
MySQL START TRANSACTION;
이후에 트랜잭션을 이용하여 수행하고 싶은 처리를 적어 나간다.
만약 문제가 발생했을 경우에는 ROLLBACK;
을 실행하여 트랜잭션 내의 처리를 돌릴 수 있다.
은행 계좌 예시 (A계좌와 B 계좌에 10만 원씩 들어있는 상태)
1. A 계좌에서 B 계좌로 10만 원의 송금을 하는 액션
2. B 계좌에서 A 계좌로 10만원의 송금을 하는 액션
▶ 동시에 실행되었다고 가정
A 계좌에서 B 계좌로 10만 원의 송금을 하는 액션
처리가 실행되면,B 계좌 예금을 플러스 10만 원 한다
가 실행되었다. B 계좌 예금을 플러스 10만 원 한다
와 A계좌 예금을 플러스 10만 원 한다
의 처리를 진행할 수 없고, 어느 쪽의 액션도 멈춰버렸다. ▶ 데드락어느 한쪽의 처리를 종료시켜야 한다.
예를 들어,
- 트랜잭션 내의 처리 시간을 단축하거나,
- 트랜잭션에서 액세스하는 데이터의 순서를 통일하는 대책을 생각할 수 있다.
ex) 계좌 간의 송금을 예로,
어느 쪽의 트랜잭션 A도 계좌의 데이터 갱신 후에 B 계좌의 데이터를 갱신하면 교착을 회피할 수 있다.
- 복수의 트랜잭션 처리가 동시에 같은 데이터를 조작하는 것으로, 서로 상대의 처리가 종료되기를 기다리는 상태가 되어 다음 처리로 진행되지 않게 되어버리는 것을
데드락
이라고 부른다.
- 데드락이 일어나 버린 경우라면 롤백으로 어느 한쪽의 처리를 종료시킬 필요가 있다.
- 트랜잭션 내의 처리 시간을 단축하거나 트랜잭션으로부터 접근하는 데이터의 순서를 통일하는 등 처음부터 데드락이 일어나지 않게 주의한다.