跨线程共享 django 事务

Posted

技术标签:

【中文标题】跨线程共享 django 事务【英文标题】:Share django transaction across threads 【发布时间】:2021-09-12 03:19:01 【问题描述】:

我有一个问题,在使用 gunicorn (gevent) 运行的 django (3.2) Web 应用程序中实现的一个 API 必须从多个 API 获取不同的价格并将这些价格存储在数据库 (Postgres 13) 中,然后再返回客户端. 我想将插入放在同一个事务中,所以如果发生意外情况,则不会插入任何内容。

我现在首先调用所有 api,每个 api 都在一个绿色线程 (gevent) 中,在它们全部返回后,我批量插入结果。

但事实证明,我真的很好奇我是否可以让不同的线程(绿色或非绿色)共享同一个事务。我看到 psycopg2 可以以非阻塞方式执行。 现在的问题是每次我在 django 中启动线程时,新线程都在新事务中。我将深入研究 django db 后端源以了解发生了什么,但也许有人可以将其清除。

Tldr;不同线程可以在同一个事务中执行查询吗?

【问题讨论】:

在 gunicorn (gevent) 上运行。所以我猜有些东西是由gevent修补的。不确定是否整个线程模块。我得检查一下 【参考方案1】:

您绝对不想尝试在没有某种锁定机制的情况下在多个线程之间共享单个事务/postgres 连接,以确保它们不会以某种导致错误的令人讨厌的方式交错连接上的活动。

相反,一个更简单、更安全的解决方案是从主请求线程启动您的绿色线程,然后gevent.join([<green thread1>, <green thread2>...]) 将它们全部从同一个主请求线程启动。每个绿色线程都会从 API 中获取数据,并将其作为每个线程的出口返回。

然后让主请求线程遍历每个退出的绿色线程对象(greenlet)并通过Greenlet.get() 获取每个对象的返回值。然后使用其正常的事务/连接在主请求线程上进行插入。

【讨论】:

以上是关于跨线程共享 django 事务的主要内容,如果未能解决你的问题,请参考以下文章

跨线程共享内存访问

如果只有一个线程使用互斥锁,跨线程的共享内存会损坏吗?

如何在php中跨线程共享全局变量?

jmeter跨线程组获取cookie或jmeter线程组共享cookie-笔者亲测

PHP - 跨所有 php 线程访问全局变量

ASP.NET MVC3 如何通过跨 Action 调用共享单个 AsyncManager 实例来避免多线程错误?