From 1f89983b71f30e8cc69912b2b4f4c7a6ec738fdd Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 30 Nov 2021 09:06:29 -0500 Subject: [PATCH] scoped_session adjustments * fix typo, change to a note the async scoped session note * more dragons re: threading.local() Change-Id: I76266507510e4014456d992656f4aadf6d03ba4a (cherry picked from commit 912bdcc8075c640a4f3d9e0194f57b5bdcfc6f2b) --- doc/build/orm/contextual.rst | 17 +++++++++++++++++ lib/sqlalchemy/orm/scoping.py | 8 ++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/doc/build/orm/contextual.rst b/doc/build/orm/contextual.rst index 2e4dbd93b0..eafdee4276 100644 --- a/doc/build/orm/contextual.rst +++ b/doc/build/orm/contextual.rst @@ -19,6 +19,21 @@ The object is the :class:`.scoped_session` object, and it represents a registry pattern, a good introduction can be found in `Patterns of Enterprise Architecture `_. +.. warning:: + + The :class:`.scoped_session` registry by default uses a Python + `threading.local() `_ + in order to track :class:`_orm.Session` instances. **This is not + necessarily compatible with all application servers**, particularly those + which make use of greenlets or other alternative forms of concurrency + control, which may lead to race conditions (e.g. randomly occurring + failures) when used in moderate to high concurrency scenarios. + Please read :ref:`unitofwork_contextual_threadlocal` and + :ref:`session_lifespan` below to more fully understand the implications + of using ``threading.local()`` to track :class:`_orm.Session` objects + and consider more explicit means of scoping when using application servers + which are not based on traditional threads. + .. note:: The :class:`.scoped_session` object is a very popular and useful object @@ -103,6 +118,8 @@ underlying :class:`.Session` being maintained by the registry:: The above code accomplishes the same task as that of acquiring the current :class:`.Session` by calling upon the registry, then using that :class:`.Session`. +.. _unitofwork_contextual_threadlocal: + Thread-Local Scope ------------------ diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index df3012df1e..7b22894531 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -125,11 +125,11 @@ class scoped_session(ScopedSessionMixin): See :ref:`unitofwork_contextual` for a tutorial. - ..warning:: + .. note:: - When using :ref:`asyncio_toplevel` the async - version :class:`_asyncio.async_scoped_session` should be - used instead. + When using :ref:`asyncio_toplevel`, the async-compatible + :class:`_asyncio.async_scoped_session` class should be + used in place of :class:`.scoped_session`. """ -- 2.47.3