isolation_level execution option

Issue #2001 resolved
Mike Bayer repo owner created an issue

fairly straightforward. this would apply to a Connection for its lifespan (with docs clarifying this), and to be as safe as possible the state is unconditionally removed at the pool level:

diff -r 09961886961668dcf452a1139eb8584bf48e2539 lib/sqlalchemy/engine/base.py
--- a/lib/sqlalchemy/engine/base.py Mon Dec 13 10:23:59 2010 -0500
+++ b/lib/sqlalchemy/engine/base.py Tue Dec 14 11:17:40 2010 -0500
@@ -825,7 +825,9 @@
                 engine._execution_options.union(_execution_options)
         else:
             self._execution_options = engine._execution_options
-
+        if 'isolation_level' in self._execution_options:
+            self._set_isolation_level()
+            
     def _branch(self):
         """Return a new Connection which references this Connection's
         engine and connection; but does not have close_with_result enabled,
@@ -860,14 +862,31 @@

             result = connection.execution_options(stream_results=True).\
                                 execute(stmt)
-            
+        
+        Note that some options necessarily affect the underying DBAPI
+        connection for the lifespan of the originating 
+        :class:`.Connection`, and are not per-execution.  In this 
+        case we refer to the "isolation_level" setting, which applies
+        a new transaction isolation level to the underlying DBAPI
+        connection.  This setting is not removed until the underying
+        DBAPI connection is returned to the connection pool.
+        
         The options are the same as those accepted by 
         :meth:`sqlalchemy.sql.expression.Executable.execution_options`.

         """
         c = self._clone()
         c._execution_options = c._execution_options.union(opt)
+        if 'isolation_level' in opt:
+            c._set_isolation_level()
+        
         return c
+
+    def _set_isolation_level(self):
+        self.dialect.set_isolation_level(self.connection, 
+                                self.execution_options['isolation_level']('isolation_level'))
+        self.connection._connection_record.finalize_callback = \
+                    self.dialect.reset_isolation_level

     @property
     def closed(self):
diff -r 09961886961668dcf452a1139eb8584bf48e2539 lib/sqlalchemy/pool.py
--- a/lib/sqlalchemy/pool.py    Mon Dec 13 10:23:59 2010 -0500
+++ b/lib/sqlalchemy/pool.py    Tue Dec 14 11:17:40 2010 -0500
@@ -250,6 +250,8 @@


 class _ConnectionRecord(object):
+    finalize_callback = None
+    
     def __init__(self, pool):
         self.__pool = pool
         self.connection = self.__connect()
@@ -348,6 +350,9 @@
         if echo:
             pool.logger.debug("Connection %r being returned to pool", 
                                     connection)
+        if connection_record.finalize_callback:
+            connection_record.finalize_callback(connection)
+            del connection_record.finalize_callback 
         if pool.dispatch.on_checkin:
             pool.dispatch.on_checkin(connection, connection_record)
         pool._return_conn(connection_record)

this can be moved to 0.7.xx if needed.

Comments (2)

  1. Log in to comment