LoginSignup
0
0

More than 3 years have passed since last update.

【Django】通勤中に書籍で学んだこと(デフォルトのDBトランザクション)

Posted at

経緯

最近通勤中に読んでる以下の書籍から学んだことをピックアップします。
https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Django-%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%80%8A%E5%9F%BA%E7%A4%8E%E7%B7%A8%E3%80%8B-%E6%A8%AA%E7%80%AC-%E6%98%8E%E4%BB%81/dp/4802094744

DjangoのデフォルトのDBトランザクション

Djangoではモデルクラスのモデルマネージャ(objects)を経由してDBとクエリ(SQL文)をやり取りします。
そして、モデルマネージャでクエリを実行した場合、発行されたSQLがDDLであったとしてもその時点でDBに反映(commit)されるとのことです。
これは存じておりませんでした。。

極端な例ですが、以下のようになるそうです。

views.py
# import省略

def update(request):
    # 処理省略
    TableA.objects.save() # この時点でコミット
    TableB.objects.delete() # この時点でコミット 

    raise Exception # 例外発生 
    # ここまでに実行されたクエリはテーブルへ反映済み。ロールバックされない。
    # 処理省略

しかし、settings.pyの「DATABASES」にプロパティを追加すると挙動が変わるとのことです。

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

上記設定により1リクエスト単位でトランザクションが管理されるようになります。

views.py
# import省略

def update(request):
    # 処理省略
    TableA.objects.save()
    TableB.objects.delete()
    # 処理省略
    # リクエスト内で例外が発生しなかった場合はトランザクションがcommitされる

まとめ

今後、ログ出力機能を現在開発中のアプリケーションに埋め込んで実際に挙動が変化する旨を確認してみようと思います。
本日は書き溜めのみ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0