it is entirely closed out and is not held in memory. See :ref:`pool_switching`
for guidelines on how to disable pooling.
-.. _threadlocal_strategy:
-
-Using the Threadlocal Execution Strategy
-========================================
-
-The "threadlocal" engine strategy is an optional feature which
-can be used by non-ORM applications to associate transactions
-with the current thread, such that all parts of the
-application can participate in that transaction implicitly without the need to
-explicitly reference a :class:`.Connection`.
-
-.. deprecated:: 1.3
-
- The "threadlocal" engine strategy is deprecated, and will be removed
- in a future release.
-
- This strategy is designed for a particular pattern of usage which is
- generally considered as a legacy pattern. It has **no impact** on the
- "thread safety" of SQLAlchemy components or one's application. It also
- should not be used when using an ORM
- :class:`~sqlalchemy.orm.session.Session` object, as the
- :class:`~sqlalchemy.orm.session.Session` itself represents an ongoing
- transaction and itself handles the job of maintaining connection and
- transactional resources.
-
- .. seealso::
-
- :ref:`change_4393_threadlocal`
-
-Enabling ``threadlocal`` is achieved as follows::
-
- db = create_engine('mysql://localhost/test', strategy='threadlocal')
-
-The above :class:`.Engine` will now acquire a :class:`.Connection` using
-connection resources derived from a thread-local variable whenever
-:meth:`.Engine.execute` or :meth:`.Engine.contextual_connect` is called. This
-connection resource is maintained as long as it is referenced, which allows
-multiple points of an application to share a transaction while using
-connectionless execution::
-
- def call_operation1():
- engine.execute("insert into users values (?, ?)", 1, "john")
-
- def call_operation2():
- users.update(users.c.user_id==5).execute(name='ed')
-
- db.begin()
- try:
- call_operation1()
- call_operation2()
- db.commit()
- except:
- db.rollback()
-
-Explicit execution can be mixed with connectionless execution by
-using the :meth:`.Engine.connect` method to acquire a :class:`.Connection`
-that is not part of the threadlocal scope::
-
- db.begin()
- conn = db.connect()
- try:
- conn.execute(log_table.insert(), message="Operation started")
- call_operation1()
- call_operation2()
- db.commit()
- conn.execute(log_table.insert(), message="Operation succeeded")
- except:
- db.rollback()
- conn.execute(log_table.insert(), message="Operation failed")
- finally:
- conn.close()
-
-To access the :class:`.Connection` that is bound to the threadlocal scope,
-call :meth:`.Engine.contextual_connect`::
-
- conn = db.contextual_connect()
- call_operation3(conn)
- conn.close()
-
-Calling :meth:`~.Connection.close` on the "contextual" connection does not :term:`release`
-its resources until all other usages of that resource are closed as well, including
-that any ongoing transactions are rolled back or committed.
-
.. _dbapi_connections:
Working with Raw DBAPI Connections
When the first :class:`.Engine` is operated upon, the :class:`.Session` can be said
to have left the "begin" state and entered "transactional" state. For each
:class:`.Engine` encountered, a :class:`.Connection` is associated with it,
-which is acquired via the :meth:`.Engine.contextual_connect` method. If a
+which is acquired via the :meth:`.Engine.connect` method. If a
:class:`.Connection` was directly associated with the :class:`.Session` (see :ref:`session_external_transaction`
for an example of this), it is
added to the transactional state directly.
s.add(A(data="d1", deferred_data="d2"))
s.commit()
- def _session_fixture(self):
+ def _session_fixture(self, **kw):
return ShardedSession(
shards={"main": testing.db},
shard_chooser=lambda *args: "main",
id_chooser=lambda *args: ["fake", "main"],
query_chooser=lambda *args: ["fake", "main"],
+ **kw
)
def test_refresh(self):
session.expire(a1)
eq_(a1.data, "d1")
+ def test_autocommit_session(self):
+ A = self.classes.A
+ session = self._session_fixture(autocommit=True)
+ a1 = session.query(A).set_shard("main").first()
+
+ eq_(a1.data, "d1")
+
class LazyLoadIdentityKeyTest(fixtures.DeclarativeMappedTest):
def _init_dbs(self):