Django Logo

[Django]トランザクションを設定する方法まとめ

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

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です