Djangoでオブジェクトに対してsave()やdelete()をするとその瞬間にデータベースに反映されるとのこと。
例えば一連の処理の中で例外が発生した場合、例外が発生した時点より前にsave()していた分はデータベースに反映されている。
こういうのはデータの一貫性が確保されない恐れがある(トランザクションが考慮されない)。
デフォルトでは上記のような仕様だけど、一連の処理の中で登録などをまとめてデータベースにコミットさせたい場合の方法もある。
1. 全ての処理にトランザクションを適用してしまう
config/settings.py
DATABASES = {
'default': {
'ENGINE': ...,
'NAME': 'hoge',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '5432',
'ATOMIC_REQUESTS': True, # これを追加
}
}
全ての処理にトランザクションが適用される。
処理をまとめてコミットする。
例外が発生した場合、ロールバックされる。
ATOMIC_REQUESTS: True を指定した状態で特定の処理のみトランザクションを適用したくない時は
処理の前に@transaction.non_atomic_requestsを付ける。
@transaction.non_atomic_requests
def create_hogehoge(request):
...
...
...
2. 指定の処理のみにトランザクションを適用する
処理の前に@transaction.atomicを付ける。
@transaction.atomic
def fuga(request):
...
...
...
もしくはwith transaction.atomic():で対象の処理を囲み、囲んだ範囲のみ適用させる。
def fuga(request):
...
...
...
with transaction.atomic(): # この範囲のみトランザクションが適用される。
...
...
...
...save()