트랜잭션

트랜잭션은 데이터베이스에서 중요한 개념이다. 나 또한 공부하면서 많이 접했지만 도통 이해하기가 힘들었다. 실무를 시작하고 나서 왜 트랜잭션이 중요한지 깨닫게 되었고, 예전의 나처럼 실무를 접해보지 않아 트랜잭션이 무엇이고 왜 중요한지 이해가 되지 않는 사람들을 위해 이 글을 작성해보려고 한다.

트랜잭션(Transaction)은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다.

위의 정의를 좀 쉽게 풀어보자면 **데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 **는 DML 즉 INSERT, UPDATE, DELETE, SELECT 들을 알맞게 사용해서 하나의 작업을 구현하는 것이라고 생각하면 된다. 또한 이 쿼리를 실행할 때 모두 성공(수행)해야 작업이 정상적으로 처리됨 뜻한다.

어떤 하나의 기능을 구현하게 해주는 쿼리들 중에서 한개의 쿼리가 실패했다면 이 전의 쿼리들은 rollback 되어야 하고, 모든 쿼리가 성공했다면 commit 을 해줘야한다. Commit과 Rollback

본인이 어떤 은행의 계좌이체 서비스를 직접 개발한다고 생각해보자. 상황은 A가 친구 B에게 5만원을 이체하려고 한다.

현재 A 계좌에는 10만원이 있고 B는 3만원이 있다. 만약 이체가 성공적으로 끝나게 되면 A 계좌에는 5만원, B 계좌에는 8만원이 남아야한다.

위의 로직을 짜보면 먼저 A 잔액을 SELECT 한 후 이체하려는 금액 5만원이 잔액보다 적은지, 큰지 확인 후 잔액이 크다면 이체를 할 수 있을 것이다. 그러면 A 계좌 잔액 - price 해서 나온 금액 을 UPDATE 한다

1
2
3
SELECT money FROM account WHERE name = 'A';

UPDATE account SET money = money - 50000 WHERE name = 'A' 

SELECT

UPDATE

이후 B 의 통장 잔고 잔액 + priceUPDATE 한다.

1
UPDATE account SET money = money + 50000 WHERE name = 'B'

UPDATE

위 시트를 보면 계좌이체가 성공했음을 볼 수 있다. 트랜잭션의 모든 쿼리가 성공했으니 commit을 하면 된다.

여기서 계좌이체 트랜잭션을 A 계좌 SELECT 부터 B 통장 잔고 UPDATE 까지 잡는다는 것을 알 수 있다.

  • A 계좌 SELECT
  • A 계좌 UPDATE
  • B 계좌 UPDATE

이렇게 트랜잭션을 잡은 이유는 이 쿼리들이 모두 성공해야 계좌이체가 성공하게 되기 때문이다. 이 트랜잭션에서 하나의 쿼리가 실패하게 된다면 작업은 아예 실패가 되어야 한다.

만약에 A 계좌 UPDATE는 성공하고 B 계좌 UPDATE는 실패했는데 작업이 정상적으로 처리된다면 A는 돈을 입금했음에도 불구하고 B 계좌에는 돈이 들어오지 않아 B가 A에게 왜 돈을 안보내냐고 짜증을 내며 전화를 할 것이다. 그리고 A 와 B는 은행 서비스에 신뢰가 떨어지게 되고 결국 해당 은행은 망하게 될 것이다.

UPDATE 부분은 이해가 가는데 왜 SELECT 부분도 같이 잡아야 할까? 이유는 A가 계좌이체 할 동안 다른 사람이 A 계좌에 접근하는 것을 막아야 하기 때문이다. A 계좌 SELECT 해서 10만원이 남아있다는 것을 확인하고 5만원을 빼려고 하는데 UPDATE 하기 전, 즉 SELECT와 UPDATE 사이에 C가 A 계좌에 2만원을 이체한다면 어떻게 될까? 현재 프로그램은 A의 계좌 잔액을 10 - 5 인 5만원으로 UPDATE 할 것이다. 하지만 이것은 잘못되었다. C가 2만원을 입금했으니 남은 잔액은 7만원이 되어야 한다. 이러한 문제를 막기 위해서 SELECT 까지 한꺼번에 트랜잭션으로 잡아 다른 사람이 A의 계좌에 접근하지 못하게 막아놔야 한다.

이렇게 트랜잭션은 중요하다. 이제부터 기능을 만들 때 어떻게 트랜잭션을 잡아야 잘했다고 소문이 날 지 고민해보자!