带有重试行为的 Go sql 包、PostgreSQL 和 PgBouncer

Posted

技术标签:

【中文标题】带有重试行为的 Go sql 包、PostgreSQL 和 PgBouncer【英文标题】:Go sql package, PostgreSQL and PgBouncer with behavior on retry 【发布时间】:2021-12-18 18:03:41 【问题描述】:

让我们想象一下我们有 PostgreSQL 和 PgBouncer(使用事务模式)。 我们还计划执行以下交易:

BEGIN;

UPDATE a ...;
UPDATE b ...;
SELECT c ...;
UPDATE d ...;

COMMIT;

当交易开始时,PgBouncer 为我们提供连接。 然后我们执行:

UPDATE a; -- successful
UPDATE b; -- successful
SELECT a; -- successful
UPDATE d; -- failed, because PgBouncer restarted.

然后我们尝试使用 go DB 客户端重试

UPDATE d;

第三次我们获取连接并执行查询。这个查询是在同一个事务中执行还是在新的连接上执行导致状态不一致?

或者每条语句都使用某个标识符执行,可以说它与某个事务相关?

【问题讨论】:

【参考方案1】:

我不能 100% 确定,因为我不熟悉 PgBouncer 或 Postgres 的内部结构,但由于交易没有标识,因此交易绑定到连接是有道理的。因此,只要 TCP/SQL 连接没有重新启动,您就应该能够恢复。但是,如果任何应用程序重新启动,那么事务就会消失。

【讨论】:

感谢您的回答。我也有同样的看法,但想再检查一次。

以上是关于带有重试行为的 Go sql 包、PostgreSQL 和 PgBouncer的主要内容,如果未能解决你的问题,请参考以下文章

从java调用带有UDT参数的postgres函数给SQL尚未实现异常

带有循环的 Postgres SQL 脚本

执行块的最长时间............带有重试和中间延迟

带有嵌套 SQL 查询或如何查找最后一个 INET 的 Postgres 视图

带有Java的Postgres我无法插入数据

带有postgres sql的spring boot框架,运行时发生异常