プログラミング

[Django]トランザクションを設定する

プログラミング
この記事は約3分で読めます。
スポンサーリンク

Djangoはデフォルトでクエリが即座にコミットされるんですが、それだと処理中に例外が発生した場合などにロールバックされず、データの整合性を保つことができなくなることがあります。データの整合性を保つために、1つのリクエストの処理を1つのトランザクションにまとめるための設定方法を説明したいと思います。

スポンサーリンク

前提条件

  • Python:3.8.2
  • Django:3.0.8

実装方法

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'db',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'ATOMIC_REQUESTS': True,  # 追加
    }
}

setting.pyDATABESES'ATOMIC_REQUESTS': Trueを追加します。

これで一つのリクエストの開始から終了までを一つのトランザクションにまとめることができます。リクエスト内で複数のクエリ実行時に途中で例外が発生した場合、ロールバックされ途中までの処理はなかったことになります。

注意点

ATOMIC_REQUESTSを設定する方法ではView関数の処理だけがトランザクションとしてまとめられるので、ミドルウェアなどは対象外となります。

トランザクションを個別に設定する

ATOMIC_REQUESTSを使用せず、各処理毎に個別にトランザクションを設定したい場合は@transaction.atomicを使用します。

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    foo()

with文を使用してトランザクションを設定する

with文を使用してトランザクションを設定することもできます。

from django.db import transaction

def viewfunc(request):
    foo()  # このコードは即時コミットされます

    with transaction.atomic():
        # このブロックの中は1つのトランザクションとして扱われます
        bar()

最後に

システム開発していると1リクエストで複数のレコードの更新や複数のテーブルにデータを追加・編集することもよくあると思います。そういう場合、トランザクションを設定し例外発生時にはロールバックさせることでデータの整合性を保つことが必要になってくると思います。適切にトランザクションを設定し、データの整合性のあるシステムを開発したいですね。

スポンサーリンク
スポンサーリンク
KoEをフォローする
CodeLab

コメント

タイトルとURLをコピーしました