【问题标题】:how is Django persistent database connections thread safe?Django 持久数据库连接线程如何安全?
【发布时间】:2023-04-09 23:42:01
【问题描述】:

在 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()

【问题讨论】:

    标签: django multithreading django-orm thread-local


    【解决方案1】:

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

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

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

    【讨论】:

    • 是的,但是每个请求/响应周期都会填充connections 对象吗?我的印象是它在import django.db 期间填充
    • 是的!知道了。所以在import django.db 期间没有填充任何内容,除了connections 对象被实例化。当代码中遇到connections['default'] 时,它会延迟加载连接。
    猜你喜欢
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 2010-09-21
    相关资源
    最近更新 更多