트랜잭션은 데이터베이스의 상태를 변화시키는 하나의 논리적 작업 단위입니다. 여러 개의 SQL 문장들이 모여 하나의 트랜잭션을 구성하며, 이들은 모두 성공하거나 모두 실패해야 합니다.
A 계좌에서 B 계좌로 10만원을 이체하는 경우:
1. A 계좌에서 10만원 차감
2. B 계좌에 10만원 추가
이 두 작업은 반드시 함께 성공하거나 함께 실패해야 합니다. 만약 A 계좌에서만 돈이 빠지고 B 계좌에 입금되지 않는다면 큰 문제가 발생하겠죠?
BEGIN TRANSACTION;
UPDATE account SET balance = balance - 100000 WHERE id = 'A';
UPDATE account SET balance = balance + 100000 WHERE id = 'B';
-- 둘 다 성공해야만 COMMIT, 하나라도 실패하면 ROLLBACK
COMMIT;
BEGIN TRANSACTION;
INSERT INTO orders VALUES (1, '상품A', 50000);
UPDATE inventory SET stock = stock - 1 WHERE product = '상품A';
COMMIT; -- 변경사항 확정
BEGIN TRANSACTION;
DELETE FROM orders WHERE order_id = 100;
-- 실수로 잘못 삭제한 경우
ROLLBACK; -- 삭제 취소, 원상복구
BEGIN TRANSACTION;
INSERT INTO orders VALUES (1, '상품A', 30000);
SAVEPOINT sp1;
INSERT INTO orders VALUES (2, '상품B', 50000);
SAVEPOINT sp2;
INSERT INTO orders VALUES (3, '상품C', 70000);
-- 상품C 주문만 취소하고 A, B는 유지
ROLLBACK TO sp2;
COMMIT; -- 상품A, B 주문만 확정
격리 수준이 높을수록 데이터 무결성은 보장되지만, 동시성은 낮아집니다.
-- 나쁜 예: 트랜잭션이 너무 큼
BEGIN TRANSACTION;
SELECT * FROM large_table; -- 시간이 오래 걸리는 조회
UPDATE orders SET status = 'completed';
COMMIT;
-- 좋은 예: 필요한 부분만 트랜잭션으로
SELECT * FROM large_table; -- 트랜잭션 밖에서 조회
BEGIN TRANSACTION;
UPDATE orders SET status = 'completed';
COMMIT;
-- Auto Commit 모드가 아닌 경우 명시적으로 제어
BEGIN TRANSACTION;
-- SQL 작업들
COMMIT; -- 또는 ROLLBACK
BEGIN TRY
BEGIN TRANSACTION;
-- SQL 작업들
COMMIT;
END TRY
BEGIN CATCH
ROLLBACK;
-- 에러 처리
END CATCH
✅ ACID 특성 암기: 원자성, 일관성, 격리성, 지속성
✅ TCL 명령어: COMMIT, ROLLBACK, SAVEPOINT
✅ 격리 수준 순서: READ UNCOMMITTED < READ COMMITTED < REPEATABLE READ < SERIALIZABLE
✅ 이상 현상: Dirty Read, Non-Repeatable Read, Phantom Read
✅ 트랜잭션 상태: Active → Partially Committed → Committed 또는 Failed → Aborted
TCL은 데이터베이스에서 트랜잭션을 제어하기 위한 명령어로 SQL 문으로 수행된 작업을 저장하거나 취소하는 역할을 한다.
정말 어려운 것같다