From ffa58ae3247a0f99225d4b797137c0ddf4ffd77d Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Tue, 5 Mar 2024 11:14:21 +0100 Subject: [PATCH 1/3] Anticipate PendingRollbackError in ``check_database_connection`` --- lib/galaxy/model/base.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/model/base.py b/lib/galaxy/model/base.py index 829bc773ec6d..bc2c149e7913 100644 --- a/lib/galaxy/model/base.py +++ b/lib/galaxy/model/base.py @@ -19,6 +19,7 @@ ) from sqlalchemy import event +from sqlalchemy.exc import PendingRollbackError from sqlalchemy.orm import ( scoped_session, Session, @@ -66,8 +67,12 @@ def check_database_connection(session): by rolling back the invalidated transaction. Ref: https://docs.sqlalchemy.org/en/14/errors.html#can-t-reconnect-until-invalid-transaction-is-rolled-back """ - if session and session.connection().invalidated: - log.error("Database transaction rolled back due to invalid state.") + try: + if session and session.connection().invalidated: + log.error("Database transaction rolled back due to invalid state.") + session.rollback() + except PendingRollbackError: + log.error("Database transaction rolled back.") session.rollback() From fb89a2651b88093390c1f53966344d1135c13229 Mon Sep 17 00:00:00 2001 From: John Davis Date: Tue, 5 Mar 2024 15:55:46 -0500 Subject: [PATCH 2/3] Explicitly check for transaction state --- lib/galaxy/model/base.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/galaxy/model/base.py b/lib/galaxy/model/base.py index bc2c149e7913..e1f22fbc447f 100644 --- a/lib/galaxy/model/base.py +++ b/lib/galaxy/model/base.py @@ -19,7 +19,6 @@ ) from sqlalchemy import event -from sqlalchemy.exc import PendingRollbackError from sqlalchemy.orm import ( scoped_session, Session, @@ -67,13 +66,10 @@ def check_database_connection(session): by rolling back the invalidated transaction. Ref: https://docs.sqlalchemy.org/en/14/errors.html#can-t-reconnect-until-invalid-transaction-is-rolled-back """ - try: - if session and session.connection().invalidated: - log.error("Database transaction rolled back due to invalid state.") - session.rollback() - except PendingRollbackError: - log.error("Database transaction rolled back.") + assert session + if not session.get_transaction().is_active or session.connection().invalidated: session.rollback() + log.error("Database transaction rolled back due to inactive session transaction or invalid connection state.") # TODO: Refactor this to be a proper class, not a bunch. From 149e281a4ca058c31c62ee67f312fc9a09e886eb Mon Sep 17 00:00:00 2001 From: John Davis Date: Tue, 5 Mar 2024 17:18:01 -0500 Subject: [PATCH 3/3] session may be a scoped_session and may not have a transaction --- lib/galaxy/model/base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/galaxy/model/base.py b/lib/galaxy/model/base.py index e1f22fbc447f..d866f6ae38cc 100644 --- a/lib/galaxy/model/base.py +++ b/lib/galaxy/model/base.py @@ -67,7 +67,10 @@ def check_database_connection(session): Ref: https://docs.sqlalchemy.org/en/14/errors.html#can-t-reconnect-until-invalid-transaction-is-rolled-back """ assert session - if not session.get_transaction().is_active or session.connection().invalidated: + if isinstance(session, scoped_session): + session = session() + trans = session.get_transaction() + if (trans and not trans.is_active) or session.connection().invalidated: session.rollback() log.error("Database transaction rolled back due to inactive session transaction or invalid connection state.")