Django持久数据库连接线程如何安全?

时间:2016-01-09 15:03:07

标签: django multithreading django-orm thread-local

在django中,持久数据库连接由threading.local实现。此代码位于类django.db.utils.ConnectionHandler中。由于此类在django.db.__init.__.py中实例化,因此当我们执行import django.db时,它会被实例化。这会在请求/响应周期中的某个地方发生。对于同一线程中的后续请求,甚至同一进程中的不同线程django.db.__init__.py将不会被执行,因为它已经被加载。

所以我的问题是它不会共享同一进程中所有线程的连接。我在这里错过了什么吗?

我觉得像下面这样的东西应该可以正常工作

# file db/__init__.py
connections = threading.local()
connections.connections = ConnectionHandler()

1 个答案:

答案 0 :(得分:3)

ConnectionHandler不是连接 - 它只处理连接。它通过将它们存储在self._connections thread.local实例上,以完全线程安全的方式完成此操作。

ConnectionHandler会覆盖__getitem__以支持线程本地连接。当您访问connections['default']时,会查看default上是否存在self._connections属性,该属性是本地线程。如果是,那将是与当前线程的默认数据库的连接。如果没有,它将创建一个新的并在self._connections上设置它。其他线程将无法访问此连接,因为它是在线程本地对象上设置的。

最后,它几乎归结为公共API。在线程本地对象上设置ConnectionHandler也会起作用,但公共API会比当前更复杂,因为用户代码将手动需要检查当前线程的处理程序是否存在。