From 9cbe235810b7c0c24d2556b4bb581b0207812e2d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 4 Feb 2015 17:07:15 -0500 Subject: - A warning is emitted if the ``isolation_level`` parameter is used with :meth:`.Connection.execution_options` when a :class:`.Transaction` is in play; DBAPIs and/or SQLAlchemy dialects such as psycopg2, MySQLdb may implicitly rollback or commit the transaction, or not change the setting til next transaction, so this is never safe. - Added new parameter :paramref:`.Session.connection.execution_options` which may be used to set up execution options on a :class:`.Connection` when it is first checked out, before the transaction has begun. This is used to set up options such as isolation level on the connection before the transaction starts. - added new documentation section detailing best practices for setting transaction isolation with sessions. fixes #3296 --- lib/sqlalchemy/engine/__init__.py | 2 ++ lib/sqlalchemy/engine/base.py | 14 ++++++++++++++ lib/sqlalchemy/engine/default.py | 6 ++++++ 3 files changed, 22 insertions(+) (limited to 'lib/sqlalchemy/engine') diff --git a/lib/sqlalchemy/engine/__init__.py b/lib/sqlalchemy/engine/__init__.py index f512e260a..7a14cdfb5 100644 --- a/lib/sqlalchemy/engine/__init__.py +++ b/lib/sqlalchemy/engine/__init__.py @@ -275,6 +275,8 @@ def create_engine(*args, **kwargs): :ref:`MySQL Transaction Isolation ` + :ref:`session_transaction_isolation` - for the ORM + :param label_length=None: optional integer value which limits the size of dynamically generated column labels to that many characters. If less than 6, labels are generated as diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 8d816b7fd..8d6dd636a 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -222,6 +222,19 @@ class Connection(Connectable): is returned to the connection pool, i.e. the :meth:`.Connection.close` method is called. + .. warning:: The ``isolation_level`` execution option should + **not** be used when a transaction is already established, that + is, the :meth:`.Connection.begin` method or similar has been + called. A database cannot change the isolation level on a + transaction in progress, and different DBAPIs and/or + SQLAlchemy dialects may implicitly roll back or commit + the transaction, or not affect the connection at all. + + .. versionchanged:: 0.9.9 A warning is emitted when the + ``isolation_level`` execution option is used after a + transaction has been started with :meth:`.Connection.begin` + or similar. + .. seealso:: :paramref:`.create_engine.isolation_level` @@ -235,6 +248,7 @@ class Connection(Connectable): :ref:`MySQL Transaction Isolation ` + :ref:`session_transaction_isolation` - for the ORM :param no_parameters: When ``True``, if the final parameter list or dictionary is totally empty, will invoke the diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index f6c2263b3..17d2e2531 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -395,6 +395,12 @@ class DefaultDialect(interfaces.Dialect): self._set_connection_isolation(connection, opts['isolation_level']) def _set_connection_isolation(self, connection, level): + if connection.in_transaction(): + util.warn( + "Connection is already established with a Transaction; " + "setting isolation_level may implicitly rollback or commit " + "the existing transaction, or have no effect until " + "next transaction") self.set_isolation_level(connection.connection, level) connection.connection._connection_record.\ finalize_callback.append(self.reset_isolation_level) -- cgit v1.2.1