Python异步事务psycopg2

4
可以使用psycopg2进行异步I/O(可以在此处阅读),但是我不确定如何进行异步事务。考虑以下操作序列:
  • Green Thread 1开始事务T
  • GT1发出更新
  • GT2发出一个事务性更新
  • GT1发出更新
  • GT1提交事务T
我认为GT1的更新与GT2的更新冲突。
现在根据文档

从同一连接创建的游标不是隔离的,即由游标对数据库所做的任何更改都会立即被其他游标看到。

因此,我们无法在游标上实现上述流程。我们可以在不同的连接上实现它,但由于我们正在进行异步操作,因此生成(潜在地)成千上万个数据库连接可能是不好的(更不用说Postgres不能处理这么多的连接)。
另一种选择是使用连接池并重复使用它们。但是,如果我们发出X个并行事务,则所有其他绿色线程都会被阻塞,直到某个连接可用。因此,实际有用的绿色线程数量为〜X(假设应用程序与数据库绑定严重),这引起了问题:为什么我们要使用异步呢?
现在,这个问题实际上可以推广到DB API 2.0。也许真正的答案是DB API 2.0不适合异步编程?那么我们如何在Postgresql上进行异步io呢?也许是其他库?
或者可能是因为postgresql协议实际上是同步的?能否随时“写入”任何事务(每个连接)将是完美的。为此,Postgresql必须公开事务的ID。这可行吗?也许两阶段提交是答案?
还是我漏掉了什么?
编辑:这似乎是SQL的普遍问题,因为“BEGIN; COMMIT;”语义不能有效地异步使用。

当在多个 with 语句中使用时,相同的连接将建立单独的事务。参考链接 - Clodoaldo Neto
首先,with不能在异步模式下使用。其次,我认为这是不可行的,至少根据这个SO帖子来看:https://dev59.com/BGgu5IYBdhLWcg3wDS4G 这与我的BEGIN; COMMIT;语义的结论一致。实际上,这个问题是关于并行事务的。 - freakish
1个回答

2

实际上你可以在异步情况下使用BEGIN;和COMMIT;。您需要设置连接池并确保每个绿色线程都获得自己的连接(就像多线程应用程序中的真实线程一样)。

您不能使用psycopg2的内置事务处理。


是的,这就是我写的。但这远非理想,因为这样你实际上限制了绿色线程的数量,使其等于池大小。其他绿色线程必须等待可用连接(如果是 db 重型应用程序)。 - freakish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接