트랜잭션
사용 테이블
orders — 주문 (상태, 금액, 일시)
products — 상품 (이름, 가격, 재고, 브랜드)
customers — 고객 (등급, 포인트, 가입채널)
payments — 결제 (방법, 금액, 상태)
학습 범위
BEGIN, COMMIT, ROLLBACK, SAVEPOINT, RELEASE, atomicity, concurrency control
1. 가장 기본적인 트랜잭션을 실행하세요. temp_account 테이블을 만들고, 두 계좌를 INSERT한 뒤
가장 기본적인 트랜잭션을 실행하세요. temp_account 테이블을 만들고, 두 계좌를 INSERT한 뒤 COMMIT하세요.
힌트 1: BEGIN; → INSERT 문 2개 → COMMIT; 순서입니다. COMMIT 전까지는 다른 연결에서 변경 내용이 보이지 않습니다.
정답
2. ROLLBACK으로 변경을 취소하세요. 김철수의 잔액을 0으로 만드는 실수를 하고, ROLLBACK으로 되돌
ROLLBACK으로 변경을 취소하세요. 김철수의 잔액을 0으로 만드는 실수를 하고, ROLLBACK으로 되돌리세요.
힌트 1: BEGIN; → UPDATE → 결과 확인 → ROLLBACK; → 복구 확인. ROLLBACK은 BEGIN 이후의 모든 변경을 취소합니다.
정답
3. 원자성(Atomicity)을 확인하세요. 김철수 → 이영희에게 30,000원 이체. 출금과 입금을 하나의 트
원자성(Atomicity)을 확인하세요. 김철수 → 이영희에게 30,000원 이체. 출금과 입금을 하나의 트랜잭션으로 묶으세요.
힌트 1: 트랜잭션 안에서 UPDATE 2번: 한쪽은 balance - 30000, 다른 쪽은 balance + 30000. 두 UPDATE가 모두 성공해야 COMMIT합니다.
정답
4. 실패 시 ROLLBACK하세요. 잔액(70,000)보다 큰 금액(500,000)을 이체하려고 합니다. 잔액
실패 시 ROLLBACK하세요. 잔액(70,000)보다 큰 금액(500,000)을 이체하려고 합니다. 잔액 부족을 확인하고 ROLLBACK하세요.
힌트 1: 출금 UPDATE 후 잔액이 음수인지 SELECT로 확인합니다. 음수라면 ROLLBACK.
정답
5. 여러 INSERT를 트랜잭션으로 묶어 성능을 확인하세요. temp_log에 여러 건의 로그를 INSERT하세
여러 INSERT를 트랜잭션으로 묶어 성능을 확인하세요. temp_log에 여러 건의 로그를 INSERT하세요.
힌트 1: SQLite에서 트랜잭션 없이 INSERT하면 매 건마다 디스크에 쓰기가 발생합니다. BEGIN/COMMIT으로 묶으면 한 번만 씁니다.
정답
CREATE TABLE temp_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
BEGIN;
INSERT INTO temp_log (message) VALUES ('로그 1');
INSERT INTO temp_log (message) VALUES ('로그 2');
INSERT INTO temp_log (message) VALUES ('로그 3');
INSERT INTO temp_log (message) VALUES ('로그 100');
COMMIT;
SELECT COUNT(*) AS total FROM temp_log;
6. SAVEPOINT를 사용하여 부분 롤백하세요. 3번째 삽입만 취소하고 나머지는 유지하세요.
SAVEPOINT를 사용하여 부분 롤백하세요. 3번째 삽입만 취소하고 나머지는 유지하세요.
힌트 1: SAVEPOINT sp1; → INSERT → SAVEPOINT sp2; → INSERT → ROLLBACK TO sp2;로 sp2 이후 변경만 취소합니다.
정답
BEGIN;
INSERT INTO temp_account (id, name, balance) VALUES (3, '박민수', 150000);
SAVEPOINT sp_after_park;
INSERT INTO temp_account (id, name, balance) VALUES (4, '정수연', 80000);
SAVEPOINT sp_after_jung;
INSERT INTO temp_account (id, name, balance) VALUES (5, '오류데이터', -999);
ROLLBACK TO sp_after_jung;
COMMIT;
SELECT * FROM temp_account ORDER BY id;
7. 중첩 SAVEPOINT를 사용하세요. 여러 단계의 데이터 수정에서 원하는 지점으로 돌아가세요.
중첩 SAVEPOINT를 사용하세요. 여러 단계의 데이터 수정에서 원하는 지점으로 돌아가세요.
힌트 1: SAVEPOINT는 이름으로 구분됩니다. ROLLBACK TO B는 B 이후의 변경만 취소하고 A ~ B까지의 변경은 유지합니다.
정답
SELECT id, name, balance FROM temp_account ORDER BY id;
BEGIN;
UPDATE temp_account SET balance = balance + 10000 WHERE id = 1;
SAVEPOINT sp_a;
UPDATE temp_account SET balance = balance + 20000 WHERE id = 2;
SAVEPOINT sp_b;
UPDATE temp_account SET balance = balance - 50000 WHERE id = 3;
ROLLBACK TO sp_b;
UPDATE temp_account SET balance = balance + 5000 WHERE id = 3;
COMMIT;
SELECT id, name, balance FROM temp_account ORDER BY id;
8. SAVEPOINT를 활용한 일괄 처리: 모든 계좌에 이자 1%를 지급하세요.
SAVEPOINT를 활용한 일괄 처리: 모든 계좌에 이자 1%를 지급하세요.
힌트 1: 전체 계좌에 일괄 적용 후 확인하는 방식으로 풀어봅니다.
정답
SELECT id, name, balance FROM temp_account ORDER BY id;
BEGIN;
SAVEPOINT sp_before_interest;
UPDATE temp_account
SET balance = balance + CAST(balance * 0.01 AS INTEGER);
SELECT id, name, balance,
CAST(balance * 0.01 AS INTEGER) AS interest
FROM temp_account ORDER BY id;
COMMIT;
SELECT id, name, balance FROM temp_account ORDER BY id;
9. RELEASE SAVEPOINT를 이해하세요. SAVEPOINT를 만들고, 정상 처리가 확인되면 RELEAS
RELEASE SAVEPOINT를 이해하세요. SAVEPOINT를 만들고, 정상 처리가 확인되면 RELEASE하세요.
힌트 1: RELEASE SAVEPOINT sp1;은 해당 SAVEPOINT를 삭제합니다. 이후 ROLLBACK TO sp1은 불가능해집니다. RELEASE는 COMMIT이 아닙니다.
정답
10. 트랜잭션 내에서 DDL의 동작을 확인하세요. CREATE TABLE 후 ROLLBACK하면 테이블이 사라지나
트랜잭션 내에서 DDL의 동작을 확인하세요. CREATE TABLE 후 ROLLBACK하면 테이블이 사라지나요?
힌트 1: SQLite에서 BEGIN → CREATE TABLE → INSERT → ROLLBACK을 실행하면 테이블 생성 자체가 취소됩니다.
정답
11. 주문 처리 트랜잭션: 잔액 차감 → 잔액 확인 → 거래 기록. 음수면 ROLLBACK.
주문 처리 트랜잭션: 잔액 차감 → 잔액 확인 → 거래 기록. 음수면 ROLLBACK.
힌트 1: UPDATE → SELECT로 잔액 확인 → 음수면 ROLLBACK, 양수면 INSERT + COMMIT.
정답
12. 포인트 이체 트랜잭션: 이영희에서 박민수에게 50,000 포인트 이체. SAVEPOINT 사용.
포인트 이체 트랜잭션: 이영희에서 박민수에게 50,000 포인트 이체. SAVEPOINT 사용.
힌트 1: 출금 → SAVEPOINT → 입금 → 이체 기록 → COMMIT. 입금에서 문제가 생기면 SAVEPOINT로 돌아갈 수 있습니다.
정답
BEGIN;
UPDATE temp_account SET balance = balance - 50000 WHERE id = 2;
SAVEPOINT sp_withdrawal;
SELECT balance FROM temp_account WHERE id = 2;
UPDATE temp_account SET balance = balance + 50000 WHERE id = 3;
INSERT INTO temp_log (message)
VALUES ('이영희 → 박민수 50,000 이체');
COMMIT;
SELECT id, name, balance FROM temp_account ORDER BY id;
13. 일괄 등급 업데이트를 트랜잭션으로 처리하세요. 잔액 기준 등급 부여 (200,000+: VIP, 100,00
일괄 등급 업데이트를 트랜잭션으로 처리하세요. 잔액 기준 등급 부여 (200,000+: VIP, 100,000+: GOLD, 그 외: SILVER).
힌트 1: BEGIN → DELETE(기존 데이터 제거) → INSERT ... SELECT로 등급 계산 → COMMIT.
정답
CREATE TABLE temp_grade (
account_id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
grade TEXT NOT NULL,
balance INTEGER NOT NULL
);
BEGIN;
DELETE FROM temp_grade;
INSERT INTO temp_grade (account_id, name, grade, balance)
SELECT
id, name,
CASE
WHEN balance >= 200000 THEN 'VIP'
WHEN balance >= 100000 THEN 'GOLD'
ELSE 'SILVER'
END,
balance
FROM temp_account;
COMMIT;
SELECT * FROM temp_grade ORDER BY balance DESC;
14. 복잡한 비즈니스 시나리오: 주문 취소 처리. 취소 기록 → 환불 → 완료 기록을 SAVEPOINT로 단계별
복잡한 비즈니스 시나리오: 주문 취소 처리. 취소 기록 → 환불 → 완료 기록을 SAVEPOINT로 단계별 처리하세요.
힌트 1: SAVEPOINT를 단계별로 사용하면 어디서 실패했는지 파악하기 쉽습니다. 최종적으로 문제가 없으면 COMMIT합니다.
정답
BEGIN;
SAVEPOINT sp_step1;
INSERT INTO temp_log (message) VALUES ('주문 취소 요청 - 고객: 김철수');
SAVEPOINT sp_step2;
UPDATE temp_account SET balance = balance + 50000 WHERE id = 1;
SAVEPOINT sp_step3;
INSERT INTO temp_log (message) VALUES ('환불 완료 - 김철수 +50,000원');
COMMIT;
SELECT id, name, balance FROM temp_account WHERE id = 1;
SELECT id, message, created_at FROM temp_log ORDER BY id DESC LIMIT 3;
15. 정리: 트랜잭션 연습에서 만든 모든 임시 테이블을 삭제하세요. 삭제 자체도 하나의 트랜잭션으로 묶으세요.
정리: 트랜잭션 연습에서 만든 모든 임시 테이블을 삭제하세요. 삭제 자체도 하나의 트랜잭션으로 묶으세요.
힌트 1: SQLite에서는 DDL도 트랜잭션에 포함됩니다. BEGIN → DROP TABLE 여러 번 → COMMIT이 가능합니다.