0Pricing
Python Academy · レッスン

トランザクションとコンテキストマネージャ

安全にコミットとロールバックを行います

「トランザクションとコンテキストマネージャ」はCoddyKit上の無料Python Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPython Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Python Academyコースには全4レッスンが含まれています。

トランザクションとは

トランザクションは複数の文をひとまとめにし、すべて成功するか、すべて失敗するようにします。これにより、データの整合性が保たれます。

SQLiteは、データを変更する文の前にトランザクションを自動的に開始します。

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
print('Table ready for transactions')
conn.close()

保存するにはコミット

conn.commit()を呼び出すまで、変更は永続化されません。それまでは現在のトランザクション内にだけ存在します。

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
cur.execute('INSERT INTO accounts (balance) VALUES (100)')
conn.commit()
print('Committed')
conn.close()

ロールバック

conn.rollback()は、直前のコミット以降に行われたすべての変更を取り消します。問題が発生したときに使用します。

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
conn.commit()
cur.execute('INSERT INTO accounts (balance) VALUES (100)')
conn.rollback()
cur.execute('SELECT COUNT(*) FROM accounts')
print('Rows after rollback:', cur.fetchone()[0])
conn.close()

送金

複数の更新を同期させる必要がある場合に、トランザクションは特に役立ちます。銀行振込では、1つの口座から引き落とし、別の口座に入金します。両方を実行するか、どちらも実行しない必要があります。

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
cur.execute('INSERT INTO accounts (id, balance) VALUES (1, 100)')
cur.execute('INSERT INTO accounts (id, balance) VALUES (2, 50)')
cur.execute('UPDATE accounts SET balance = balance - 30 WHERE id = 1')
cur.execute('UPDATE accounts SET balance = balance + 30 WHERE id = 2')
conn.commit()
cur.execute('SELECT id, balance FROM accounts')
print(cur.fetchall())
conn.close()

try/exceptによるエラー処理

トランザクションをtry/exceptで囲みます。エラーが発生したらロールバックし、途中までの変更によってデータが壊れないようにします。

import sqlite3
conn = sqlite3.connect(':memory:')
cur = conn.cursor()
cur.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
try:
    cur.execute('INSERT INTO accounts (id, balance) VALUES (1, 100)')
    cur.execute('INSERT INTO accounts (id, balance) VALUES (1, 200)')
    conn.commit()
except sqlite3.IntegrityError:
    conn.rollback()
    print('Rolled back after error')
conn.close()

コンテキストマネージャーとしての接続

with conn:を使うと、成功時には自動的にコミットされ、ブロック内で例外が発生した場合はロールバックされます。

import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER)')
with conn:
    conn.execute('INSERT INTO accounts (balance) VALUES (100)')
print('Auto-committed via with block')
conn.close()

例外発生時の自動ロールバック

with conn:ブロックで例外が発生すると、トランザクションは自動的にロールバックされます。ただし、接続自体は開いたままです。

import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE accounts (id INTEGER PRIMARY KEY)')
try:
    with conn:
        conn.execute('INSERT INTO accounts (id) VALUES (1)')
        conn.execute('INSERT INTO accounts (id) VALUES (1)')
except sqlite3.IntegrityError:
    print('Block rolled back automatically')
count = conn.execute('SELECT COUNT(*) FROM accounts').fetchone()[0]
print('Rows:', count)
conn.close()

接続のclosing()

contextlib.closingヘルパーを使うと、ブロックの終了時にclose()が必ず呼び出され、接続が解放されます。

import sqlite3
from contextlib import closing
with closing(sqlite3.connect(':memory:')) as conn:
    conn.execute('CREATE TABLE t (id INTEGER)')
    print('Used inside closing()')
print('Connection closed automatically')

2つのパターンの組み合わせ

closing(...)の内側にwith conn:をネストすると、トランザクションを管理しながら、接続が確実に閉じられるようにできます。

import sqlite3
from contextlib import closing
with closing(sqlite3.connect(':memory:')) as conn:
    conn.execute('CREATE TABLE t (id INTEGER, v TEXT)')
    with conn:
        conn.execute('INSERT INTO t VALUES (1, ?)', ('hello',))
    print(conn.execute('SELECT * FROM t').fetchall())

isolation_level

接続のisolation_levelは、トランザクションを開始するタイミングを制御します。デフォルトではSQLiteに任せますが、Noneに設定すると自動コミットモードが有効になります。

import sqlite3
conn = sqlite3.connect(':memory:')
print('Default isolation_level:', repr(conn.isolation_level))
conn.isolation_level = None
print('Now autocommit:', conn.isolation_level)
conn.close()

トランザクションが重要な理由

トランザクションがないと、更新の途中でクラッシュした場合に、データが中途半端な状態で残る可能性があります。トランザクションは一連の変更をアトミック、つまり分割できない単位にします。これにより、データの整合性が保護されます。

import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE log (msg TEXT)')
with conn:
    conn.execute('INSERT INTO log VALUES (?)', ('all or nothing',))
print('Atomic write done')
conn.close()

確認テスト

トランザクションについての知識を確認しましょう。

まとめ

トランザクションを安全に管理する方法を学びました。

  • commit()は変更を保存し、rollback()は変更を取り消します
  • リスクのある書き込みは、ロールバックを行うtry/exceptで囲みます
  • with conn:は自動的にコミットまたはロールバックします
  • contextlib.closingは接続が閉じられることを保証します

よくある質問

「トランザクションとコンテキストマネージャ」レッスンは無料ですか?

はい。「トランザクションとコンテキストマネージャ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Python Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Python Academyコースには全4レッスンが含まれています。

「トランザクションとコンテキストマネージャ」で何を学びますか?

安全にコミットとロールバックを行います ブラウザで直接実行するハンズオンコードでPython Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Python Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPython Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「トランザクションとコンテキストマネージャ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPython Academyレッスンでコードを書いて実行できますか?

はい。すべてのPython Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 接続とテーブルの作成
  2. Insert、Select、Update、Delete
  3. パラメータ化クエリ
  4. トランザクションとコンテキストマネージャ
← Python Academyに戻る