데이터베이스(쉬운코드)

14. Transaction과 Transcation의 속성 ACID

youbing 2024. 12. 9. 15:25
본 내용은 유튜버 쉬운코드의 강의 "데이터베이스"를 참고하여 작성하였습니다.

 

예제를 통해 배워보는 Transcation 개념

예제 : J가 H에게 20만원을 이체한다면 각자의 계좌는 어떻게 변경돼야 할까요?

  • J의 계좌에서 -20만원 후 H의 계좌에서 +20만원
-- J의 계좌에서 -20만원
UPDATE account SET balance = balance - 20000 WHERE id = 'J';

-- H의 계좌에서 +20만원
UPDATE account SET balance = balance + 20000 WHERE id = 'H';
  • 이체는 위의 두 작업이 모두 정상 처리돼야만 성공하는 단일 작업

Transcation 개념 정리

  • 단일한 논리적인 작업 단위 (a single logical unit of work)
  • 논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 없게 만든 것이 transcation이다.
  • transcation의 SQL문들 중에 일부만 성공해서 DB에 반영되는 일은 일어나지 않는다.

SQL을 통해 Transcation 사용해보기

account DB의 초기 상태 / 이체 후 상태

-- transcation 시작
START TRANSCATION;

-- 원하는 작업들 수행
UPDATE account SET balance = balance - 20000 WHERE id = 'J';
UPDATE account SET balance = balance + 20000 WHERE id = 'H';

-- 작업 내용을 저장하고 transcation 종료
COMMIT;
  • COMMIT : 지금까지 작업한 내용을 DB에 영구적으로 저장하고 transcation을 종료한다.

ROLLBACK

  • 지금까지 작업들을 모두 취소하고 transcation 이전 상태로 되돌리고 transcation을 종료한다.
START TRANSCATION;
UPDATE account SET balance = balance - 20000 WHERE id = 'J';
-- SELECT * FROM account; -> J의 계좌에 2만원이 출금되어 있음.

ROLLBACK;
-- SELECT * FROM account; -> J의 계좌에 2만원이 출금되기 전으로 복구됨.

autocommit

  • 각각의 SQL문을 자동으로 transcation 처리해주는 개념
  • SQL문이 성공적으로 실행하면 자동으로 commit 한다.
  • 실행 중에 문제가 있었다면 알아서 rollback 한다.

 

  • MySQL에서는 default로 autocommit이 enabled 되어 있다. (SELECT @@AUTOCOMMIT; 으로 확인 가능)
  • 다른 RDBMS에서도 대부분 같은 기능을 제공한다.

autocommit이 켜져 있다.

 

-- default로 autocommit이 켜져 있는 상태
INSERT INTO account VALUES ('W', 1000000); -- 정상적으로 실행되어 바로 DB에 저장됨.
SELECT * FROM account; -- W의 계좌가 추가되어 나옴.
SET autocommit=0; -- autocommit off

DELETE FROM account WHERE balance <= 1000000; -- rollback 하면 이전 상태로 돌아갈 수 있음.
SELECT * FROM account; -- 100만원 이하의 계좌가 다 삭제됨.

ROLLBACK;
SELECT * FROM account; -- 삭제되기 전 상태로 돌아옴.

 

START TRANSCATION;

UPDATE account SET balance = balance - 20000 WHERE id = 'J';
UPDATE account SET balance = balance + 20000 WHERE id = 'H';

COMMIT;
  • START TRANSCATION은 실행과 동시에 auticommit이 off 됨.
  • COMMIT / ROLLBACK과 함께 transcation이 종료되면 원래 autocommit 상태로 돌아간다.

Transcation 사용패턴

  1. transaction을 시작(start)한다.
  2. 데이터를 읽거나 쓰는 등의 SQL문들을 포함해서 로직을 수행한다.
  3. 일련의 과정들이 문제없이 동작했다면 transcation을 commit 한다.
  4. 중간에 문제가 발생했다면 transcation을 rollback 한다.

Java에서 Transcation 사용 예제

public void transfer(String fromId, String toId, int amount) {
  try {
    Connection connection = ...;      // get DB connection
    connection.setAutoCommit(false);  // means START TRANSACTION
    ...  // update at fromId
    ...  // update at toId
    connection.commit();
  } catch (Exception e) {
    ...
    connection.rollback();
    ...
  } finally {
    connection.setAutoCommit(true);
  }
}

 


Spring에서 Transcation 사용 예제

@Transactional
public void transfer(String fromId, String toId, int account) {
  ... // update at fromId
  ... // update at toId
}
  • 스프링(부트)의 @Transcational을 사용하여 transaction과 관련된 코드를 숨길 수 있음.

ACID

Atomicity

Consistency

Isolation

Durability (영존성)

  • 트랜잭션이 어떤 속성을 지녀야 하는지를 의미함.

Atomicity

이체를 성공하려면 두 작업이 모두 성공해야 하며, 하나라도 실패하면 이체 자체가 실패함.

  • ALL or NOTHING
  • transaction은 논리적으로 쪼개질 수 없는 작업 단위이기 때문에 내부의 SQL문들이 모두 성공해야 한다.
  • 중간에 SQL문이 실패하면 지금까지의 작업을 모두 취소하여 아무 일도 없었던 것처럼 rollback 한다.

 

  • commit 실행 시 DB에 영구적으로 저장하는 것은 DBMS가 담당하는 부분이다.
  • rollback 실행 시 이전 상태로 되돌리는 것도 DBMS가 담당하는 부분이다.
  • 개발자는 언제 commit 하거나 rollback 할 지를 챙겨야 한다.

Consistency

예제 : J(80만원)가 H(220만원)에게 100만원을 추가로 이체한다면?

  • 전제 조건 : CREATE TABLE account 할 때 check (balance >= 0) 을 추가해둠.

작업을 수행할 때 기존에 DB에 설정된 조건을 깨뜨리지 않아야 함.

  • transaction은 DB 상태를 consistent 상태에서 또 다른 consistent 상태로 바꿔줘야 한다.
  • constraints, trigger 등을 통해 DB에 정의된 rules을 transaction이 위반했다면 rollback 해야 한다.
    • trigger가 DB의 consistent를 깨뜨리는지 확인하는 용도로도 사용 가능
  • transaction이 DB에 정의된 rule을 위반했는지는 DBMS가 commit 전에 확인하고 알려준다.
  • 그 외에 application 관점에서 transaction이 consistent하게 동작하는지는 개발자가 챙겨야 한다.

Isolation

예제 J가 H에게 20만원을 이체할 때 H도 ATM에서 본인 계좌에 30만원을 입금한다면?

Isolation이 되지 않았을 때의 문제점. (read는 원래의 잔고를 불러오는 작업)

  • 여러 transaction들이 동시에 실행될 때도 혼자 실행되는 것처럼 동작하게 만든다.
  • DBMS는 여러 종류의 isolation level을 제공한다.
  • 개발자는 isolation level 중에 어떤 level로 transaction을 동작시킬지 설정할 수 있다.
  • concurrency control의 주된 목표가 isolation이다.

Durability (영존성)

  • commit 된 transaction은 DB에 영구적으로 저장된다.
  • 즉, DB system에 문제(power fail or DB crash)가 생겨도 commit된 transaction은 DB에 남아 있는다.
  • '영구적으로 저장한다'라고 할 때는 일반적으로 '비휘발성 메모리(HDD, SSD, ...)에 저장함'을 의미한다.
  • 기본적으로 transaction의 durability는 DBMS가 보장한다.

참고 사항

1. transaction을 어떻게 정의해서 쓸 지는 개발자가 정하는 것입니다. 구현하려는 기능과 ACID 속성을 이해해야 transaction을 잘 정의할 수 있습니다.

 

2. transaction의 ACID와 관련해서 개발자가 챙겨야 하는 부분들이 있습니다. DBMS가 모든 것을 알아서 해주는 것은 아닙니다.

 

3. transaction SQL 예제는 MySQL을 사용했습니다. 다른 RDBMS에서는 문법이 조금씩 다를 수 있습니다.