commit이나 rollback같은 명령어를 명시적으로 사용할 필요가 없음INSERT INTO users (id, name) VALUES (1, 'Alice'); -- 이 문장 실행 후 즉시 커밋됨
UPDATE products SET price = 100 WHERE id = 5; -- 이 문장 실행 후 즉시 커밋됨
START TRANSACTION; -- 트랜잭션 시작
UPDATE accounts SET balance = balance - 1000 WHERE user_id = 'A'; -- 1. A 계좌에서 출금
UPDATE accounts SET balance = balance + 1000 WHERE user_id = 'B'; -- 2. B 계좌로 입금
COMMIT; -- 두 작업 모두 성공했으므로 영구 반영
-- 만약 2번 문에서 오류가 났다면, ROLLBACK; 명령어로 1번 작업까지 모두 취소됨
SavePoint
일반적인 트랜잭션 관리에서는 ROLLBACK 명령어를 사용하면 트랜잭션이 시작된 지점 전체로 모든 변경사항이 취소, 하지만 SAVEPOINT를 사용하면 중간에 오류가 발생했을 경우 오류가 발생한 단계 이전까지만 작업을 되돌릴 수 있음
-- 트랜잭션 시작 START TRANSACTION; -- 1단계 작업 실행 INSERT INTO orders (id, item) VALUES (101, 'Laptop'); -- 1단계 작업 후 저장점 설정 (성공 가정) SAVEPOINT step1_complete; -- 2단계 작업 실행 UPDATE inventory SET stock = stock - 1 WHERE item = 'Laptop'; -- 2단계 작업 후 저장점 설정 SAVEPOINT step2_complete; -- 3단계 작업 실행 (여기서 오류가 발생했다고 가정) -- 예를 들어, 고객 잔액이 부족하여 결제 처리(UPDATE)가 실패함 -- 오류 발생 시, 2단계 작업까지만 유지하고 3단계의 실패한 작업만 취소하고자 함 ROLLBACK TO step2_complete; -- 2단계까지의 작업은 유효하므로, 롤백된 후 다시 시도하거나 다음 단계를 진행 -- ... -- 최종적으로 트랜잭션 커밋 COMMIT;
-- 트랜잭션 시작 명령어 없이 DML 문 실행
UPDATE products SET stock = stock - 10 WHERE product_id = 5;
-- 이 시점에서 트랜잭션이 자동으로 시작된 상태임
-- 데이터는 아직 영구 저장되지 않음
COMMIT; -- 사용자가 명시적으로 커밋해야 트랜잭션이 완료됨
다음을 하나의 트랜잭션으로 실행
이때 결제 테이블에 입력 이상 발생시 앞서 발생한 주문테이블, 주문상세테이블, 상품 재고 컬럼 수량 변경 등이 트랜잭션 이전으로 rollback되는 지 확인

SELECT * FROM pg_stat_activity ORDER BY query_start ASC;
-- wait_event_type: lock
SELECT * FROM pg_locks

-- query tool 1 (session 1)
create table prod
(
prod_id int not null unique
, stock int default 0
);
insert into prod values (101,10); insert into prod values (102,10);
BEGIN;
UPDATE prod SET stock = stock - 1 WHERE prod_id = 101;
UPDATE prod SET stock = stock + 5 WHERE prod_id = 102; -- 대기
select *
from prod
-- query tool 2(session2)
SELECT * FROM pg_stat_activity ORDER BY query_start ASC;
SELECT * FROM pg_locks
-- query tool 3(session3)
BEGIN;
UPDATE prod SET stock = stock - 1 WHERE prod_id = 102;
UPDATE prod SET stock = stock + 5 WHERE prod_id = 101; -- 대기
