]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commit
propose concurrency check for SessionTransaction
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 2 Dec 2021 14:18:11 +0000 (09:18 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 27 Dec 2021 18:13:02 +0000 (13:13 -0500)
commitcc46ea711df77540d5d658e9c7b3ab1e88288929
tree401208da0f9f783517c059fb5ccae52a2b43b8dd
parentfd99a4aa808f91f87d0a678708dd9c2b131fda04
propose concurrency check for SessionTransaction

the discussion at #7387 refers to a condition that seems
to happen in the wild also, such as [1] [2] [3], it's not
entirely clear why this specific spot is how this occurs,
however it's maybe that when the connection is being acquired
from the pool, under load there might be a wait on the connection
pool, leading to more time for another errant thread to be
calling .close(), just a theory.

in this patch we propose using decorators and context managers
along with declarative state declarations to block reentrant
or concurrent calls to methods that conflict with expected
state changes.

The :class:`_orm.Session` (and by extension :class:`.AsyncSession`) now has
new state-tracking functionality that will proactively trap any unexpected
state changes which occur as a particular transactional method proceeds.
This is to allow situations where the :class:`_orm.Session` is being used
in a thread-unsafe manner, where event hooks or similar may be calling
unexpected methods within operations, as well as potentially under other
concurrency situations such as asyncio or gevent to raise an informative
message when the illegal access first occurs, rather than passing silently
leading to secondary failures due to the :class:`_orm.Session` being in an
invalid state.

[1] https://stackoverflow.com/questions/25768428/sqlalchemy-connection-errors
[2] https://groups.google.com/g/sqlalchemy/c/n5oVX3v4WOw
[3] https://github.com/cosmicpython/code/issues/23

Fixes: #7433
Change-Id: I699b935c0ec4e5a63f12cf878af6f7a92a30a3aa
doc/build/changelog/migration_20.rst
doc/build/changelog/unreleased_20/7433.rst [new file with mode: 0644]
lib/sqlalchemy/exc.py
lib/sqlalchemy/orm/session.py
lib/sqlalchemy/orm/state_changes.py [new file with mode: 0644]
test/base/test_except.py
test/orm/test_session_state_change.py [new file with mode: 0644]