Django 持久数据库连接线程安全如何?
how is Django persistent database connections thread safe?
在django中,持久数据库连接由threading.local
实现。此代码驻留在 class django.db.utils.ConnectionHandler
中。由于此 class 是在 django.db.__init.__.py
中实例化的,因此当我们执行 import django.db
时它会被实例化。这会在 request/response 周期的某个地方发生。对于同一线程中的后续请求,甚至同一进程中的不同线程,django.db.__init__.py
将不会执行,因为它已经加载。
所以我的问题是它不会为同一进程中的所有线程共享连接。我在这里遗漏了什么吗?
我认为像下面这样的东西应该可以正常工作
# file db/__init__.py
connections = threading.local()
connections.connections = ConnectionHandler()
ConnectionHandler
不是连接 -- 它只处理连接。它以完美的 thread-safe 方式将它们存储在 self._connections
上,这是一个 thread.local
实例。
ConnectionHandler
覆盖 __getitem__
以支持 thread-local 连接。当您访问 connections['default']
时,它会查看 default
属性是否存在于 self._connections
上,这是一个本地线程。如果是,那将是当前线程到默认数据库的连接。如果没有,它将创建一个新的并将其设置为 self._connections
。其他线程将无法访问此连接,因为它是在线程本地对象上设置的。
最后它几乎归结为 public API。在 thread-local 对象上设置 ConnectionHandler
也可以,但是 public API 会比现在更复杂,因为用户代码需要手动检查是否当前线程的处理程序存在。
在django中,持久数据库连接由threading.local
实现。此代码驻留在 class django.db.utils.ConnectionHandler
中。由于此 class 是在 django.db.__init.__.py
中实例化的,因此当我们执行 import django.db
时它会被实例化。这会在 request/response 周期的某个地方发生。对于同一线程中的后续请求,甚至同一进程中的不同线程,django.db.__init__.py
将不会执行,因为它已经加载。
所以我的问题是它不会为同一进程中的所有线程共享连接。我在这里遗漏了什么吗?
我认为像下面这样的东西应该可以正常工作
# file db/__init__.py
connections = threading.local()
connections.connections = ConnectionHandler()
ConnectionHandler
不是连接 -- 它只处理连接。它以完美的 thread-safe 方式将它们存储在 self._connections
上,这是一个 thread.local
实例。
ConnectionHandler
覆盖 __getitem__
以支持 thread-local 连接。当您访问 connections['default']
时,它会查看 default
属性是否存在于 self._connections
上,这是一个本地线程。如果是,那将是当前线程到默认数据库的连接。如果没有,它将创建一个新的并将其设置为 self._connections
。其他线程将无法访问此连接,因为它是在线程本地对象上设置的。
最后它几乎归结为 public API。在 thread-local 对象上设置 ConnectionHandler
也可以,但是 public API 会比现在更复杂,因为用户代码需要手动检查是否当前线程的处理程序存在。