diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-12-02 09:18:11 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2021-12-27 13:13:02 -0500 |
commit | cc46ea711df77540d5d658e9c7b3ab1e88288929 (patch) | |
tree | 401208da0f9f783517c059fb5ccae52a2b43b8dd /lib/sqlalchemy/exc.py | |
parent | fd99a4aa808f91f87d0a678708dd9c2b131fda04 (diff) | |
download | sqlalchemy-cc46ea711df77540d5d658e9c7b3ab1e88288929.tar.gz |
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
Diffstat (limited to 'lib/sqlalchemy/exc.py')
-rw-r--r-- | lib/sqlalchemy/exc.py | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index e35c41836..e51214fd9 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -249,6 +249,15 @@ class InvalidRequestError(SQLAlchemyError): """ +class IllegalStateChangeError(InvalidRequestError): + """An object that tracks state encountered an illegal state change + of some kind. + + .. versionadded:: 2.0 + + """ + + class NoInspectionAvailable(InvalidRequestError): """A subject passed to :func:`sqlalchemy.inspection.inspect` produced no context for inspection.""" |