如何处理 FATAL:由于 idle-in-transaction 超时而终止连接

How to deal with FATAL: terminating connection due to idle-in-transaction timeout

我有一种方法,其中一些数据库操作是通过一些 API 调用发生的。这是 Spring 和 postgres 数据库的场景。我们还在 postgres DB

中为空闲事务设置了 属性
idle_in_transaction_session_timeout = 10min

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

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

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

@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 的 select 输出,并在步骤 3 中使用 select 调用的 API 输出。所以这三个步骤是相互依存的。

十分钟对于保持交易打开来说是一个非常长的时间。您的 RDBMS 服务器会自动断开您的会话,回滚事务,因为它无法判断事务是由交互式 (command-line) 用户启动的,然后没有提交它就出去吃午饭了,还是由 long-running 和你一样的任务。

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

您最好的解决方案是重构您的应用程序代码,以便它可以在另一个 API 调用的 ten-minute 响应之后开始并快速提交事务。

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

或者,您可以像这样为该连接设置事务超时,以降低系统的 out-to-lunch 风险。

SET idle_in_transaction_session_timeout = '15m';