跨线程共享 django 事务
Share django transaction across threads
我遇到一个问题,其中一个 API 在 django (3.2) 网络应用程序中实现 运行 gunicorn (gevent) 必须从多个 API 中获取不同的价格并存储return 发送给客户端之前数据库 (Postgres 13) 中的那些价格。
我想将插入放在同一个事务中,所以如果发生意外情况,则不会插入任何内容。
我现在首先调用所有 api,每个都在一个绿色线程 (gevent) 中,然后在所有这些 return 之后,我批量插入结果。
但事实证明我真的很好奇是否有可能让不同的线程(绿色或非绿色)共享同一个事务。我看到 psycopg2 可以以非阻塞方式执行。
现在的问题是每次我在 django 中启动线程时,新线程都在新事务中。我将深入研究 django 数据库后端源以了解发生了什么,但也许有人可以解决这个问题。
Tldr;不同的线程可以在同一个事务中执行查询吗?
您绝对不想在没有锁定机制的情况下尝试在多个线程之间共享单个 transaction/postgres 连接,以确保它们不会以某种令人讨厌的方式在连接上交错 activity导致错误。
相反,更简单、更安全的解决方案是从主请求线程启动绿色线程,然后 gevent.join([<green thread1>, <green thread2>...])
所有这些都从同一个主请求线程启动。每个绿色线程将从 API 获取数据,并且 return 它作为每个线程的出口。
然后让主请求线程遍历每个退出的绿色线程对象 (greenlet),并通过 Greenlet.get()
为每个对象获取 return 值。然后使用其正常的 transaction/connection.
在主请求线程上执行插入
更新
如果您想变得更复杂以获得更好的性能,您可以使用池并让每个 greenlet 将其结果放在从主线程读取的队列中。这样您就可以在结果可用时开始将结果保存到数据库,而不是等到它们全部完成。
我遇到一个问题,其中一个 API 在 django (3.2) 网络应用程序中实现 运行 gunicorn (gevent) 必须从多个 API 中获取不同的价格并存储return 发送给客户端之前数据库 (Postgres 13) 中的那些价格。 我想将插入放在同一个事务中,所以如果发生意外情况,则不会插入任何内容。
我现在首先调用所有 api,每个都在一个绿色线程 (gevent) 中,然后在所有这些 return 之后,我批量插入结果。
但事实证明我真的很好奇是否有可能让不同的线程(绿色或非绿色)共享同一个事务。我看到 psycopg2 可以以非阻塞方式执行。 现在的问题是每次我在 django 中启动线程时,新线程都在新事务中。我将深入研究 django 数据库后端源以了解发生了什么,但也许有人可以解决这个问题。
Tldr;不同的线程可以在同一个事务中执行查询吗?
您绝对不想在没有锁定机制的情况下尝试在多个线程之间共享单个 transaction/postgres 连接,以确保它们不会以某种令人讨厌的方式在连接上交错 activity导致错误。
相反,更简单、更安全的解决方案是从主请求线程启动绿色线程,然后 gevent.join([<green thread1>, <green thread2>...])
所有这些都从同一个主请求线程启动。每个绿色线程将从 API 获取数据,并且 return 它作为每个线程的出口。
然后让主请求线程遍历每个退出的绿色线程对象 (greenlet),并通过 Greenlet.get()
为每个对象获取 return 值。然后使用其正常的 transaction/connection.
更新
如果您想变得更复杂以获得更好的性能,您可以使用池并让每个 greenlet 将其结果放在从主线程读取的队列中。这样您就可以在结果可用时开始将结果保存到数据库,而不是等到它们全部完成。