본문 바로가기
C.W.K.
Stream
Lesson 08 of 10 · published

Transaction — BEGIN, COMMIT, ROLLBACK

~14 min · transactions, acid, writes

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

원자적 작업 묶음

Transaction은 여러 statement를 원자 단위 하나로 묶는 거야. 전부 적용되거나 하나도 안 되거나 둘 중 하나지. SQLite는 기본이 완전한 ACID야. statement 하나짜리도 암묵적인 transaction 안에서 돌아.

명시적으로 쓰는 모양은 셋이야.

  • BEGIN; ... COMMIT; — transaction을 열고 잘 끝나면 확정해.
  • BEGIN; ... ROLLBACK; — BEGIN 이후의 변경을 전부 없던 일로 해.
  • SAVEPOINT — 바깥 transaction 안에 중간 지점을 찍어둬. 잘 끝나면 RELEASE, 잘못되면 ROLLBACK TO로 그 지점까지만 되돌려.

transaction 모드도 셋 있어.

  • DEFERRED — 기본값이야. 필요해지는 순간에 락을 잡아.
  • IMMEDIATE — BEGIN 하는 순간 write 락을 잡아서 다른 writer를 바로 세워.
  • EXCLUSIVE — 배타 락을 잡아서 다른 reader와 writer를 전부 세워.
Tip: 다른 writer와 부딪힐 수 있는 '전부 아니면 전무' 작업이라면 BEGIN IMMEDIATE를 써. 기본인 DEFERRED는 다른 writer가 먼저 도착했을 때 COMMIT 시점에 SQLITE_BUSY로 터질 수 있는데, IMMEDIATE는 BEGIN에서 일찍 실패해줘.

Code

SQL의 명시적 transaction·sql
BEGIN IMMEDIATE;

INSERT INTO conversations(title) VALUES ('New chat');
INSERT INTO messages(conversation_id, role, content)
VALUES (last_insert_rowid(), 'user', 'Hello');

-- COMMIT 전 뭔가 실패하면 전체 batch 롤백 가능:
-- ROLLBACK;

COMMIT;
Python — context manager가 commit/rollback 처리·python
import sqlite3

conn = sqlite3.connect('demo.db')
conn.execute('PRAGMA foreign_keys = ON')

try:
    with conn:                                  # implicit BEGIN/COMMIT
        conv_id = conn.execute(
            'INSERT INTO conversations(title) VALUES (?)',
            ('New chat',)
        ).lastrowid
        conn.execute(
            'INSERT INTO messages(conversation_id, role, content) VALUES (?,?,?)',
            (conv_id, 'user', 'Hello'),
        )
        # 여기서 exception 나면 자동 ROLLBACK.
except sqlite3.IntegrityError:
    print('rolled back')

External links

Exercise

conversation 하나와 message 목록을 원자적으로 넣는 Python 함수를 써봐. 루프 한가운데서 일부러 예외를 던져서 롤백이 제대로 도는지 확인해. 그다음 writer 두 개를 동시에 돌려서 BEGIN DEFERRED와 BEGIN IMMEDIATE가 경합 상황에서 어떻게 다른지 직접 봐.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.