데이터베이스(쉬운코드)
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 사용해보기
-- 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에서도 대부분 같은 기능을 제공한다.
-- 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 사용패턴
- transaction을 시작(start)한다.
- 데이터를 읽거나 쓰는 등의 SQL문들을 포함해서 로직을 수행한다.
- 일련의 과정들이 문제없이 동작했다면 transcation을 commit 한다.
- 중간에 문제가 발생했다면 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) 을 추가해둠.
- 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만원을 입금한다면?
- 여러 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에서는 문법이 조금씩 다를 수 있습니다.