@@ -3418,6 +3418,17 @@ ProcessInterrupts(void)
34183418 IdleInTransactionSessionTimeoutPending = false;
34193419 }
34203420
3421+ if (TransactionTimeoutPending )
3422+ {
3423+ /* As above, ignore the signal if the GUC has been reset to zero. */
3424+ if (TransactionTimeout > 0 )
3425+ ereport (FATAL ,
3426+ (errcode (ERRCODE_TRANSACTION_TIMEOUT ),
3427+ errmsg ("terminating connection due to transaction timeout" )));
3428+ else
3429+ TransactionTimeoutPending = false;
3430+ }
3431+
34213432 if (IdleSessionTimeoutPending )
34223433 {
34233434 /* As above, ignore the signal if the GUC has been reset to zero. */
@@ -3632,6 +3643,15 @@ check_log_stats(bool *newval, void **extra, GucSource source)
36323643 return true;
36333644}
36343645
3646+ /* GUC assign hook for transaction_timeout */
3647+ void
3648+ assign_transaction_timeout (int newval , void * extra )
3649+ {
3650+ if (TransactionTimeout <= 0 &&
3651+ get_timeout_active (TRANSACTION_TIMEOUT ))
3652+ disable_timeout (TRANSACTION_TIMEOUT , false);
3653+ }
3654+
36353655
36363656/*
36373657 * set_debug_options --- apply "-d N" command line option
@@ -4483,25 +4503,37 @@ PostgresMain(const char *dbname, const char *username)
44834503 pgstat_report_activity (STATE_IDLEINTRANSACTION_ABORTED , NULL );
44844504
44854505 /* Start the idle-in-transaction timer */
4486- if (IdleInTransactionSessionTimeout > 0 )
4506+ if (IdleInTransactionSessionTimeout > 0
4507+ && (IdleInTransactionSessionTimeout < TransactionTimeout || TransactionTimeout == 0 ))
44874508 {
44884509 idle_in_transaction_timeout_enabled = true;
44894510 enable_timeout_after (IDLE_IN_TRANSACTION_SESSION_TIMEOUT ,
44904511 IdleInTransactionSessionTimeout );
44914512 }
4513+
4514+ /* Schedule or reschedule transaction timeout */
4515+ if (TransactionTimeout > 0 && !get_timeout_active (TRANSACTION_TIMEOUT ))
4516+ enable_timeout_after (TRANSACTION_TIMEOUT ,
4517+ TransactionTimeout );
44924518 }
44934519 else if (IsTransactionOrTransactionBlock ())
44944520 {
44954521 set_ps_display ("idle in transaction" );
44964522 pgstat_report_activity (STATE_IDLEINTRANSACTION , NULL );
44974523
44984524 /* Start the idle-in-transaction timer */
4499- if (IdleInTransactionSessionTimeout > 0 )
4525+ if (IdleInTransactionSessionTimeout > 0
4526+ && (IdleInTransactionSessionTimeout < TransactionTimeout || TransactionTimeout == 0 ))
45004527 {
45014528 idle_in_transaction_timeout_enabled = true;
45024529 enable_timeout_after (IDLE_IN_TRANSACTION_SESSION_TIMEOUT ,
45034530 IdleInTransactionSessionTimeout );
45044531 }
4532+
4533+ /* Schedule or reschedule transaction timeout */
4534+ if (TransactionTimeout > 0 && !get_timeout_active (TRANSACTION_TIMEOUT ))
4535+ enable_timeout_after (TRANSACTION_TIMEOUT ,
4536+ TransactionTimeout );
45054537 }
45064538 else
45074539 {
@@ -4554,6 +4586,13 @@ PostgresMain(const char *dbname, const char *username)
45544586 enable_timeout_after (IDLE_SESSION_TIMEOUT ,
45554587 IdleSessionTimeout );
45564588 }
4589+
4590+ /*
4591+ * If GUC is changed then it's handled in
4592+ * assign_transaction_timeout().
4593+ */
4594+ if (TransactionTimeout > 0 && get_timeout_active (TRANSACTION_TIMEOUT ))
4595+ disable_timeout (TRANSACTION_TIMEOUT , false);
45574596 }
45584597
45594598 /* Report any recently-changed GUC options */
@@ -5112,7 +5151,8 @@ enable_statement_timeout(void)
51125151 /* must be within an xact */
51135152 Assert (xact_started );
51145153
5115- if (StatementTimeout > 0 )
5154+ if (StatementTimeout > 0
5155+ && (StatementTimeout < TransactionTimeout || TransactionTimeout == 0 ))
51165156 {
51175157 if (!get_timeout_active (STATEMENT_TIMEOUT ))
51185158 enable_timeout_after (STATEMENT_TIMEOUT , StatementTimeout );
0 commit comments