데이터 베이스 트랜잭션과 트랜잭션의 매우 중요한 속성들인 ACID를 공부하고 정리했습니다.
트랜잭션
- 단일한 논리적인 작업 단위(single logical unit of work)
- 논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 없게 만든 것
- 트랜잭션의 SQL문들 중에 일부만 성공해서 DB에 반영되는 일은 일어나지 않는다.
START TRANSACTION;
UPDATE account SET balance = balance - 20000 where id = 'j';
UPDATE account SET balance = balance + 20000 where id = 'h';
COMMIT;
-
COMMIT
- 지금까지 작업한 내용을 DB에 영구적으로 저장하라
- 트랜잭션을 종료한다.
-
ROLLBACK
- 지금까지 작업들을 모두 취소하고 트랜잭션 이전 상태로 되돌린다.
- 트랜잭션을 종료한다.
-
AUTOCOMMIT
- 각각의 SQL문을 자동으로 트랜잭션 처리해주는 개념
- SQL문이 성공적으로 실행하면 자동으로 commit 한다.
- 실행 중에 문제가 있었다면 알아서 rollback 한다.
- MySQL 에서는 default 로 autocommit 이 enabled 되어 있다.
- 다른 DBMS 에서도 대부분 같은 기능을 제공한다.
참고
- START TRANSACTION 실행과 동시에 autocommit 은 off 된다.
- commit / rollback 과 함께 트랜잭션이 종료되면 원래 autocommit 상태로 돌아간다.
일반적인 transaction 사용 패턴
- transaction을 시작(begin) 한다.
- 데이터를 읽거나 쓰는 등의 SQL 문들을 포함해서 로직을 수행한다.
- 일련의 과정들이 문제없이 동작했다면 transaction을 commit 한다.
- 중간에 문제가 발생했다면 transaction을 rollback 한다.
public void transfer(String fromId, String told, int amount) {
try {
Connection connection = ... ;
connection.setAutoCommit(false);
...
...
connection.commit();
} catch (Exception e) {
...
connection.rollback();
...
} finally {
connection.setAutoCommit(true);
}
}
- 이체와 관련된 비즈니스 로직과 트랜잭션과 관련된 로직이 같이 있어 가독성이 떨어진다.
@Transactional
public void transfer(String fromId, String told, int amount) {
...
...
}
- @Transactional 메서드를 붙이면 트랜젝션과 관련된 로직을 알아서 처리해준다.
- 매서드 내부에는 이체와 관련된 로직만 써주면 된다.
ACID
트랜잭션이 어떤 속성을 가져야 하는가? 를 나타내는 개념들
- Atomicity
- Consistency
- Isolation
- Durability
Atomicity
- 원자성
- all or nothing
- transaction 은 논리적으로 쪼개질 수 없는 작업 단위이기 때문에 내부의 SQL문들이 모두 성공해야 한다.
- 중간에 SQL문이 실패하면 지금까지의 작업을 모두 취소하여 아무 일도 없었던 것처럼 rollback 한다.
- 데이터베이스의 상태가 일관적일 수 있도록 계속 유지를 해줘야함
참고
- commit 실행 시 db에 영구적으로 저장하는 것은 DBMS가 담당하는 부분이다.
- rollback 실행 시 이전 상태로 되돌리는 것도 DBMS가 담당하는 부분이다.
- 개발자는 언제 commit 하거나 rollback 할지를 챙겨야 한다.
Consistency
- 일관성
- transaction은 DB 상태를 consistent 상태에서 또 다른 consistent 상태로 바꿔줘야 한다.
- constraints, trigger 등을 통해 DB에 정의된 rules 을 transaction이 위반했다면 rollback 해야 한다.
- transaction 이 DB에 정의된 rule 을 위반했는지는 DBMS가 commit 전에 확인하고 알려준다.
- 그 외에 application 관점에서 transaction 이 consistent 하게 동작하는지는 개발자가 챙겨야 한다.
Isolation
- 격리
- 여러 transaction 들이 동시에 실행될 때도 혼자 실행되는 것처럼 동작하게 만든다.
- DBMS는 여러 종류의 isolcation 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 가 보장한다.
정리
- transaction 을 어떻게 정의 해서 쓸지는 개발자가 정하는 것.
- 구현하려는 기능과 ACID 속성을 이해해야 transaction을 잘 정의할 수 있다.
- transaction 의 ACID 와 관련해서 개발자가 챙겨야 하는 부분들이 있다.
- DBMS가 모든 것을 알아서 해주는 것은 아니다.