可以使用psycopg2进行异步I/O(可以在此处阅读),但是我不确定如何进行异步事务。考虑以下操作序列:
现在根据文档:
另一种选择是使用连接池并重复使用它们。但是,如果我们发出X个并行事务,则所有其他绿色线程都会被阻塞,直到某个连接可用。因此,实际有用的绿色线程数量为〜X(假设应用程序与数据库绑定严重),这引起了问题:为什么我们要使用异步呢?
现在,这个问题实际上可以推广到DB API 2.0。也许真正的答案是DB API 2.0不适合异步编程?那么我们如何在Postgresql上进行异步io呢?也许是其他库?
或者可能是因为postgresql协议实际上是同步的?能否随时“写入”任何事务(每个连接)将是完美的。为此,Postgresql必须公开事务的ID。这可行吗?也许两阶段提交是答案?
还是我漏掉了什么?
编辑:这似乎是SQL的普遍问题,因为“BEGIN; COMMIT;”语义不能有效地异步使用。
- Green Thread 1开始事务T
- GT1发出更新
- GT2发出一个事务性更新
- GT1发出更新
- GT1提交事务T
现在根据文档:
因此,我们无法在游标上实现上述流程。我们可以在不同的连接上实现它,但由于我们正在进行异步操作,因此生成(潜在地)成千上万个数据库连接可能是不好的(更不用说Postgres不能处理这么多的连接)。从同一连接创建的游标不是隔离的,即由游标对数据库所做的任何更改都会立即被其他游标看到。
另一种选择是使用连接池并重复使用它们。但是,如果我们发出X个并行事务,则所有其他绿色线程都会被阻塞,直到某个连接可用。因此,实际有用的绿色线程数量为〜X(假设应用程序与数据库绑定严重),这引起了问题:为什么我们要使用异步呢?
现在,这个问题实际上可以推广到DB API 2.0。也许真正的答案是DB API 2.0不适合异步编程?那么我们如何在Postgresql上进行异步io呢?也许是其他库?
或者可能是因为postgresql协议实际上是同步的?能否随时“写入”任何事务(每个连接)将是完美的。为此,Postgresql必须公开事务的ID。这可行吗?也许两阶段提交是答案?
还是我漏掉了什么?
编辑:这似乎是SQL的普遍问题,因为“BEGIN; COMMIT;”语义不能有效地异步使用。
with
语句中使用时,相同的连接将建立单独的事务。参考链接 - Clodoaldo Netowith
不能在异步模式下使用。其次,我认为这是不可行的,至少根据这个SO帖子来看:https://dev59.com/BGgu5IYBdhLWcg3wDS4G 这与我的BEGIN; COMMIT;
语义的结论一致。实际上,这个问题是关于并行事务的。 - freakish