【Django】トランザクション管理を実装する方法:ロールバックの有効化

2022.05.15 /

【Django】トランザクション管理を実装する方法:ロールバックの有効化

本記事ではDjangoで作成したWebアプリケーションに、トランザクション管理を実装(有効化)する方法について解説していきます。

Djangoでデータベースと連携させる場合、トランザクションは必ず考えなければならないことです。データの整合性を保つためにも、必要な個所にはトランザクションを有効にするべきです。トランザクションを使うことで、ビューから例外が漏れたときロールバックが実行されます。

本記事を通して、Djangoでトランザクションを有効にする方法を学びましょう。

トランザクション管理

トランザクションとは

トランザクションはデータの一貫性を確保するために一連の処理(複数のレコード操作)をひとまとめにしたものです。

例えば銀行口座への入金・送金の操作で、Aさんは自分の口座から3万円をBさんの口座へ送金し、その後現金で自分の口座へ5万円を入金したとします。トランザクション管理では、この2つの操作を1つのトランザクションとして扱います。トランザクションの流れとしては次のようになります。

  1. トランザクションの開始
  2. 口座から3万円をBさんの口座へ送金
  3. 現金5万円を口座へ入金
  4. トランザクションの終了

より詳しくトランザクションについては以下記事をご参照ください。

トランザクション管理の利点

トランザクション管理を使用する利点としては、ロールバックという機能があることです。ロールバックとはトランザクションの途中でエラーが発生したら一連の処理(レコードの追加・変更・削除)をなかったことにすることです。

例えば例に挙げた銀行口座への入金・送金で、送金は成功したが入金は失敗した場合を考えてみます。この場合、「Bさんの口座のお金は増えているが、Aさんの口座は3万円減っただけで増えていない」という結果になり、データの一貫性(整合性)が保たれていません。

このような問題を防ぐためにトランザクション管理ではエラーが発生したらロールバックを行い、データの整合性を保つようにしています。

Django:トランザクション管理の設定

デフォルト設定:オートコミットモード

Djangoのデフォルト設定では、データの保存・更新・削除といった各クエリは即座にデータベースにコミットされます。すなわちsave()やupdate()、delete()が実行された時点でデータベースに反映されるとういことです。

この各クエリが即座にデータベースにコミットされることをオートコミットと呼びます。

IT用語の確認

クエリとはSQL実行後にデータベースに送る命令文のことです。

オートコミットではなくトランザクション管理を有効にしたい場合は、次項で解説する方法で有効にする必要があります。

トランザクション管理を有効にするには

トランザクション管理を有効にするには以下の3つの方法があります。

  • 設定ファイルで「ATOMIC_REQUESTS」を有効にする
  • デコレーターの@transaction.atomicを使用する
  • transaction.atomic()とwith句を使用する

それぞれの方法はメリット・デメリットがありますので、ご自身のWebアプリケーションに合った方法を利用してください。

Django:トランザクション管理の有効化

設定ファイルで「ATOMIC_REQUESTS」を有効にする

設定ファイルsettings.pyの「DATABASES」に「ATOMIC_REQUESTS」を追加しTrueにすることでトランザクションは有効になります。

# settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
        'ATOMIC_REQUESTS': True,
    }
}

トランザクションの有効範囲は、ビュー(views.py)内の関数すべてです。ビューの開始から終了までを1つのトランザクションとしてまとめます。

ビューから例外が漏れたときロールバックが実行されます。

この方法は非常に簡単にトランザクションを有効にできます。しかしデメリットとしてはすべてのビュー(リクエスト)でトランザクションを扱うことになるため、同時アクセスが多いWebアプリケーションではパフォーマンスが低下することです。

そのためトランザクション(ATOMIC_REQUESTS)を無効化したいビューに対しては、デコレーターの@transaction.not_atomic_requestsを使用するようにしましょう。

from django.db import transaction

@transaction.non_atomic_requests
def test(request):
    …
注意

このデコレーターはATOMIC_REQUESTSが有効なときのみ利用できます

デコレーターの@transaction.atomicを使用する

指定した関数だけトランザクションを有効にしたい場合は、デコレーターの@transaction.atomicを使用します。

from django.db import transaction

@transaction.atomic
def test(request):
    # ここからトランザクションとなる
    …

この方法の特徴としては、デコレーターを付けた関数全体が1つのトランザクションになることです。

transaction.atomic()とwith句を使用する

with句とtransaction.atomic()を使用することでトランザクションを有効にできます。

from django.db import transaction

def test(request):
    func_one()  #即時コミットされる

    with transaction.atomic():
        # ここからはトランザクションとなる
        func_two()

上記からわかるように、この方法では関数内で希望した処理をトランザクションとすることができます。

まとめ

本記事「【Django】トランザクション管理を実装する方法:ロールバックの有効化」はいかがでしたか。

デフォルト設定のままではトランザクションは無効となっています。トランザクションを使うことでロールバックが有効となり、データベースの整合性を保てるようになります。

ぜひDjangoで作成したWebアプリケーションでトランザクションを利用してみてください。