Help us understand the problem. What is going on with this article?

Django内部でThreadを使う場合に意図せぬコネクションリークが発生

はじめに

Djangoの内部で時間のかかるリクエストを処理したり、バッチ処理拡張モジュールを自作する場合などに並列処理実装として自分でスレッドを作成し、利用することがある。
今回このケースで長期運用していると Too many connections が発生したので、その調査結果をメモ。

原因

  • DjangoのDBコネクションは スレッドごと に作成される
    • DBアクセスが発生する場合のみ。 モデルへのアクセスがない別スレッドはそもそもDBコネクションを生成しないので問題ない
    • コネクションを利用する際、スレッドローカル相当の機能内にコネクションが保持されており、ここに無い場合は初回アクセス時にコネクションを生成する
    • https://github.com/django/django/blob/master/django/db/utils.py#L136 の ConnectionHandlerが実体で self._connections 内にコネクションを格納
  • 自分で作った別スレッドの中でDjangoのモデルを使う場合にはDBコネクション管理を意識する必要がある
  • スレッドローカル実装の定期解放処理時に解放される場合もあるが、実装が入り組んでいる場合解放されないこともあるし、待っている間にも上限は近づいてくる

対処

I/Oコストはかかるものの、スレッド終了時にコネクションを close_all で明示的に閉じることでコネクションリークは防ぐことができる。
とはいえ、そもそも何らかの理由(おそらく処理時間の問題)があって別スレッドを立てているはずなので、コネクションの作成・解放はそこまで大きな問題にはならないはず。

from django.db import connections

def target():
    ''' 別スレッドで実行される関数 '''
    try:
        # 処理
    finally:
        connections.close_all()

ちなみに、close_all は "同一スレッド内の全てのDBを閉じる" 関数である(Djangoは設定に DATABASES として複数のDBを設定することが可能)。 別スレッドのDBを閉じたりはしない。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした