diff --git a/h/db/__init__.py b/h/db/__init__.py index a0cabd3b775..276408d60c9 100644 --- a/h/db/__init__.py +++ b/h/db/__init__.py @@ -115,6 +115,21 @@ def close_the_sqlalchemy_session(request): }) session.close() + # zope.sqlalchemy maintains an internal `id(session) => state` map for + # each active DB session which is registered with it. + # + # Ensure that this is empty at the end of the request as otherwise it + # can cause request <=> DB transaction integration to break in future + # requests if a future `Session` object reuses the same ID. + dm = zope.sqlalchemy.datamanager + if len(dm._SESSION_STATE) > 0: + log.warn('request ended with non-empty zope.sqlalchemy state', extra={ + 'data': { + 'zope.sqlalchemy.datamanager._SESSION_STATE': dm._SESSION_STATE, + }, + }) + dm._SESSION_STATE = {} + return session