트랜잭션

banjjoknim·2021년 2월 27일
0

36강. 트랜잭션

여기에서는 트랜잭션에 대해서 알아본다.

트랜잭션의 제어

START TRANSACTION
COMMIT
ROLLBACK

  • 데이터베이스는 트랙잭션이라는 기능을 제공한다.
  • INSERTUPDATE 명령으로 데이터를 추가, 갱신할 때도 트랜잭션 기능을 사용하지만 지금까지 특별히 의식할 필요는 없었다.
  • 이는 자동 커밋이라 불리는 기능이 동작했기 때문이다.

1. 트랜잭션

정규화에 의해 분할된 주문 테이블과 주문상품 테이블의 관계를 생각해보자.

  • 주문 테이블과 주문상품 테이블 사이에는 의존관계가 존재한다.
  • 주문 테이블에 행이 존재한다면 주문상품 테이블에는 적어도 하나의 행이 존재해야 한다.
  • 그렇지 않으면 주문한 상품이 없는데도 주문이 된 상태가 된다.
  • 보통은 하나 이상의 상품을 주문하므로 주문이 발생하면 주문 테이블과 주문상품 테이블 모두 행이 추가된다.
  • 물론 있다, 없다는 주문번호와 관련이 있으므로 '같은 주문번호로'라는 조건을 붙일 수 있다.

발주처리

  • 주문이 발생했을 때 어떻게 처리되는지 생각해보자. 간단히 말하자면 발주처리에 관한 것으로, 먼저 주문번호를 지정해야 한다.
  • 이때 기존 주문과 구분되는 주문번호를 발행하는 처리가 필요하다.
  • 자동 증가를 사용하면 자동적으로 번호가 부여되지만 그렇지 않은 경우에는 '번호 중 가장 큰 값을 SELECT 명령으로 가져와 그 값에 1을 더한다'라는 처리가 필요하다.
  • 최대값은 MAX()로 검색할 수 있으므로 MAX + 1이라 할 수도 있다.
  • 번호를 발행 받았다면 해당 번호를 키로 삼아 INSERT가 이루어진다.
  • 주문 테이블에는 INSERT 한 번, 주문상품 테이블에는 주문된 상품 수만큼 INSERT 명령이 실행된다.
  • 중요한 것은 복수의 테이블에 INSERT 되므로 실행되는 명령은 최소 두 번이라는 것이다.

발주처리

INSERT INTO 주문 VALUES(4, '2014-03-01', 1);
INSERT INTO 주문상품 VALUES(4, '0003', 1);
INSERT INTO 주문상품 VALUES(4, '0004', 2);
  • 여기서 INSERT 명령이 특정 원인으로 인해 에러가 발생한 경우를 가정해보자.
  • 트랜잭션 기능을 사용하지 않을 때는 문제없이 실행된 INSERT 명령을 실행 전으로 되돌릴 수 없으므로 따로 DELETE 명령을 실행해 지워야한다.
  • 즉, 위의 세 번째 INSERT 명령에서 에러가 발생했다고 치면, 앞서 실행한 두 개의 INSERT 명령에 의해 추가된 데이터를 DELETE 명령으로 삭제하는 처리가 필요하다.

2. 롤백과 커밋

  • 이처럼 몇 단계로 처리를 나누어 SQL 명령을 실행하는 경우에 트랜잭션을 자주 사용한다.
  • 트랜잭션을 사용해서 데이터를 추가한다면 에러가 발생해도 트랜잭션을 롤백(rollback)해서 종료할 수 있다.
  • 롤백하면 트랜잭션 내에서 행해진 모든 변경사항을 잃었던 것으로 할 수 있다.
  • 아무런 에러가 발생하지 않는다면 변경사항을 적용하고 트랜잭션을 종료하는데, 이때 커밋(commit)을 사용한다.
트랜잭션을 롤백하면 변경한 내용이 적용되지 않는다!

자동커밋

  • 트랜잭션을 사용해서 데이터를 추가할 때는 자동커밋을 꺼야 한다.
  • mysql 클라이언트에서 명령을 실행할 때는 자동커밋이 켜져 있는 상태이다.
  • INSERTUPDATE, DELETE가 처리될 때마다 트랜잭션은 암묵적으로 자동커밋 상태로 되어 있다.
  • 자동커밋을 끄기 위해서는 명시적으로 트랜잭션의 시작을 선언할 필요가 있다.
  • 트랜잭션을 시작할 때는 START TRANSACTION 명령을 사용한다.

트랜잭션 시작

START TRANSACTION
  • 앞서 언급한 것처럼 트랜잭션을 종료하기 위해서는 변경된 내용을 적용한 후에 종료하는 '커밋'과 적용하지 않고 종료하는 '롤백'의 두 가지 방식이 있다.
  • 커밋할 때에는 COMMIT 명령을 사용한다.

트랜잭션 내에서 실행한 명령을 적용한 후 종료

COMMIT
  • 롤백은 ROLLBACK 명령을 사용한다.

트랜잭션 내에서 실행한 명령을 파기한 후 종료

ROLLBACK
  • 트랜잭션 내에서 실행된 SQL 명령은 임시 데이터 영역에서 수행되다가, COMMIT 명령을 내리면 임시 데이터 영역에서 정식 데이터 영역으로 변경이 적용된다고 생각하면 된다.
  • ROLLBACK 명령을 내리면 임시 데이터 영역에서의 처리는 버려진다.

다음 예제에서는 트랜잭션을 사용해 발주처리를 한다. 에러가 발생하지 않은 경우의 사례로, 트랜잭션은 COMMIT을 이용해 종료한다.

트랜잭션 내에서의 발주처리

START TRANSACTION;
INSERT INTO 주문 VALUES(4, '2014-03-01', 1);
INSERT INTO 주문상품 VALUES(4, '0003', 1);
INSERT INTO 주문상품 VALUES(4, '0004', 2);
COMMIT
  • 이렇게 트랜잭션을 시작해서 SQL 명령을 실행하고 COMMIT 또는 ROLLBACK 명령으로 트랜잭션을 종료하는 일련의 처리방법을 '트랜잭션을 걸어서 실행한다' 또는 '트랜잭션 내에서 실행한다'라고 말한다.
트랜잭션을 사용해서 처리하는 것으로 간단히 데이터를 관리할 수 있다!

3. 트랜잭션 사용법

  • 발주처리와 같은 데이터 등록처리 과정에서는 대부분 트랜잭션 내에서 여러 개의 SQL 명령을 실행하게 된다.
  • 다만 하나의 명령에 트랜잭션을 걸어 실행하는 것은 별로 의미가 없다.
  • 트랜잭션 내에서 실행하는 복수의 SQL 명령은 세트 단위로 유효/무효가 된다.
  • 다시 말하면, 반드시 세트로 실행하고 싶은 SQL 명령을 트랜잭션에서 하나로 묶어 실행한다는 것이다.
  • ROLLBACK은 에러가 발생한 경우 변경사항이 적용되지 않도록 하는 목적으로 주로 사용하지만, 에러가 발생하지 않아도 ROLLBACK을 하면 변경한 내용은 파기된다.
  • 반대로 에러가 발생하더라도 COMMIT을 하면 문제없이 실행된 SQL 명령의 변경사항은 데이터베이스에 그대로 반영된다.
세트로 실행하고 싶은 SQL 명령은 트랜잭션 내에서 실행한다!
  • 트랜잭션을 시작할 때 사용하는 명령은 START TRANSACTION이라고 설명했지만 이것은 MySQL의 경우에 적용된다.
    • MySQL에서는 START TRANSACTION 외에도 BEGIN을 사용할 수 있다.
  • SQL ServerPostgreSQL에서는 BEGIN TRANSACTION 명령을 사용한다.
  • Oracle이나 DB2에서 트랜잭션을 시작하는 명령은 따로 없다. 이 또한 표준화가 진행되지 못한 부분이다.
  • 자동커밋은 클라이언트 툴의 기능이다.
  • 미들웨어도 데이터베이스 접속 시 대개 자동커밋을 한다.
  • 한편, 데이터베이스 서버에서는 언제나 트랜잭션을 걸 수 있는 상태로 SQL 명령이 실행된다.
  • 트랜잭션을 사용할 경우에는 접속형태나 클라이언트 툴의 자동커밋 사용 여부 등, 트랜잭션 관련 기능을 파악해 둘 필요가 있다.
  • DELETE 명령은 삭제 여부에 관해 사용자에게 확인하지 않는다고 설명했다.
  • 불친절한 시스템이라고 생각할 수도 있으나, DELETE 명령을 트랜잭션 내에서 실행하는 경우에는 ROLLBACK으로 삭제를 취소할 수 있다.
  • 단, 자동커밋으로 되어있는 경우에는 주의해야 한다. ROLLBACK으로 취소할 수 있는 것은 트랜잭션 내에서 실행했을 경우에 한해서이다.

profile
꿈꾸는 개발자

0개의 댓글