如何处理 FATAL: 由于空闲事务超时而终止连接

发布于 2025-01-10 20:59:26 字数 668 浏览 0 评论 0原文

我有一种方法,其中一些数据库操作是通过一些 API 调用进行的。这是 Spring 和 postgres DB 的场景。我们还在 postgres DB 中为空闲事务设置了属性

idle_in_transaction_session_timeout = 10min

现在的问题是我有时会遇到异常

org.postgresql.util.PSQLException:此连接已关闭。根本原因是致命的:由于事务空闲超时而终止连接

例如,我的代码如下所示:

@Transactional(value = "transactionManagerDC")
public void Execute()
{
     // 1. select from DB - took 2 min
     // 2. call another API - took 10 min. <- here is when the postgres close my connection
    //  3. select from DB - throws exception.

}; 

正确的设计是什么?我们使用 API 调用中步骤 1 的输出进行选择,并使用步骤 3 中使用的 API 调用的输出进行选择。所以这三个步骤是相互依赖的。

I have one method where some DB operations are happened with some API call. This is a scenario with Spring and postgres DB. We also have property set for idle transaction in postgres DB

idle_in_transaction_session_timeout = 10min

Now the issue is I do get Exception sometime

org.postgresql.util.PSQLException: This connection has been closed. Root Cause is FATAL: terminating connection due to idle-in-transaction timeout

For example, my code look like this:

@Transactional(value = "transactionManagerDC")
public void Execute()
{
     // 1. select from DB - took 2 min
     // 2. call another API - took 10 min. <- here is when the postgres close my connection
    //  3. select from DB - throws exception.

}; 

What could be the correct design for it? We are using output for select from step 1 in API call and output of that API call used in step 3 for select. So these three steps are interdependent.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

宛菡 2025-01-17 20:59:26

十分钟对于保持交易开放来说是很长的时间。您的 RDBMS 服务器会自动断开您的会话,回滚事务,因为它无法判断事务是由交互式(命令行)用户启动,然后出去吃午饭而没有提交它,还是由像您这样的长时间运行的任务启动。

开放事务可能会阻止 RDBMS 的其他用户,因此最好快速提交它们。

最好的解决方案是重构应用程序代码,以便它可以在其他 API 调用十分钟响应后开始并快速提交事务。

在不了解更多信息的情况下很难给你具体的建议。但是,您可以在调用该慢速 API 之前在行上设置某种 status = "API call in Progress" 列,并在 API 调用完成后清除事务中的该状态。

或者,您可以使用类似的方法为该连接设置事务超时,以降低系统上的午餐风险。

SET idle_in_transaction_session_timeout = '15m'; 

Ten minutes is a very long time to hold a transaction open. Your RDBMS server automatically disconnects your session, rolling back the transaction, because it cannot tell whether the transaction was started by an interactive (command-line) user who then went out to lunch without committing it, or by a long-running task like yours.

Open transactions can block other users of your RDBMS, so it's best to COMMIT them quickly.

Your best solution is to refactor your application code so it can begin, and then quickly commit, the transaction after the ten-minute response from that other API call.

It's hard to give you specific advice without knowing more. But you could set some sort of status = "API call in progress" column on a row before you call that slow API, and clear that status within your transaction after the API call completes.

Alternatively, you can set the transaction timeout for just that connection with something like this, to reduce the out-to-lunch risk on your system.

SET idle_in_transaction_session_timeout = '15m'; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文