트랜잭션은 작업의 완전성을 보장해주는 것이다. 즉 논리적인 작업 셋을 모두 완벽하게 처리하거나, 처리하지 못할 경우에는 원 상태로 복구해서 작업의 일부만 적용되는 현상(Partial update)이 발생하지 않게 만들어주는 기능이다.
하나의 논리적인 작업 셋에 하나의 쿼리가 있든 두 개 이상의 쿼리가 있든 관계없이 논리적인 작업 셋 자체가 100% 적용되거나(COMMIT을 실행했을 때) 아무것도 적용되지 않아야(ROLLBACK 또는 트랜잭션을 ROLLBACK시키는 오류가 발생했을 때) 함을 보장해주는 것이다.
lock : 동시성 제어를 위한 기능
트랜잭션 : 데이터의 정합성을 보장하기 위한 기능
commit : 데이터베이스의 변경사항을 영구적으로 저장하는 동작
→ 여러 작업이 하나의 단위로 처리되어야 할 때에는 모든 작업이 성공한 후에 커밋한다.
auto-commit : 각각의 SQL 명령문이 자동으로 commit(확정)되는 기능
SET autocommit=ON;
을 하게 되면 각 SQL문장이 실행될 때마다 자동으로 commit 된다.
INSERT, UPDATE, DELETE 등의 작업이 즉시 데이터베이서에 반영된다.
별도로 commit 명령어를 실행할 필요가 없다.
여러 작업을 하나의 단위로 묶어서 처리하려면 auto-commit을 OFF하여 트랜잭션을 수동으로 관리한다.
저희 팀은 MySQL 말고, PostgreSQL을 사용하기 때문에 PostgreSQL으로 실습해봅니다 :
postgres=# CREATE DATABASE transaction_test;
CREATE DATABASE
postgres=# -- 1. 테이블 생성
CREATE TABLE accounts (
id SERIAL PRIMARY KEY,
name VARCHAR(50),
balance DECIMAL(10,2)
);
CREATE TABLE
postgres=# -- 2. 초기 데이터 입력
INSERT INTO accounts (name, balance) VALUES
('홍길동', 1000000),
('김철수', 500000);
INSERT 0 2
postgres=# -- 3. 기본 트랜잭션 실습
BEGIN;
-- 홍길동의 계좌에서 200000원 출금
UPDATE accounts
SET balance = balance - 200000
WHERE name = '홍길동';
-- 김철수의 계좌로 200000원 입금
UPDATE accounts
SET balance = balance + 200000
WHERE name = '김철수';
-- 트랜잭션 성공 시 커밋
COMMIT;
-- 실패 시 롤백하려면: ROLLBACK;
BEGIN
UPDATE 1
UPDATE 1
COMMIT
postgres=# SELECT * FROM "accounts";
id | name | balance
----+--------+-----------
1 | 홍길동 | 800000.00
2 | 김철수 | 700000.00
(2 rows)
첫 번째 우분투 : COMMIT 안 한 상태!
postgres=# BEGIN;
-- 첫 번째 거래
UPDATE accounts
SET balance = balance - 50000
WHERE name = '홍길동';
SAVEPOINT first_transaction;
BEGIN
UPDATE 1
SAVEPOINT
postgres=*# SELECT * FROM "accounts";
id | name | balance
----+--------+-----------
2 | 김철수 | 700000.00
1 | 홍길동 | 750000.00
(2 rows)
두 번째 우분투로 DISK 확인 :
postgres=# select * from accounts;
id | name | balance
----+--------+-----------
2 | 김철수 | 700000.00
1 | 홍길동 | 750000.00
(2 rows)
첫 번째 우분투 : COMMIT 시행
postgres=*# COMMIT;
COMMIT
postgres=# select * from accounts;
id | name | balance
----+--------+-----------
2 | 김철수 | 700000.00
1 | 홍길동 | 700000.00
(2 rows)