From: Mike Bayer Date: Thu, 12 Apr 2012 18:38:52 +0000 (-0400) Subject: - [bug] If conn.begin() fails when calling X-Git-Tag: rel_0_7_7~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9273cdd6387bdf2182e595bdd5144a1792e9e1a4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - [bug] If conn.begin() fails when calling "with engine.begin()", the newly acquired Connection is closed explicitly before propagating the exception onward normally. --- diff --git a/CHANGES b/CHANGES index 96383e1d74..633695d8d3 100644 --- a/CHANGES +++ b/CHANGES @@ -48,6 +48,11 @@ CHANGES before SQLAlchemy modifies the state of the cursor. + - [bug] If conn.begin() fails when calling + "with engine.begin()", the newly acquired + Connection is closed explicitly before + propagating the exception onward normally. + - mssql - [feature] Added interim create_engine flag supports_unicode_binds to PyODBC dialect, diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 110ac4e8a1..1d25113337 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -2355,7 +2355,11 @@ class Engine(Connectable, log.Identified): """ conn = self.contextual_connect(close_with_result=close_with_result) - trans = conn.begin() + try: + trans = conn.begin() + except: + conn.close() + raise return Engine._trans_ctx(conn, trans, close_with_result) def transaction(self, callable_, *args, **kwargs): diff --git a/test/engine/test_execute.py b/test/engine/test_execute.py index 6bdbf42272..610f5e42b0 100644 --- a/test/engine/test_execute.py +++ b/test/engine/test_execute.py @@ -358,6 +358,23 @@ class ConvenienceExecuteTest(fixtures.TablesTest): testing.run_as_contextmanager(ctx, fn, 5, value=8) self._assert_fn(5, value=8) + def test_transaction_engine_ctx_begin_fails(self): + engine = engines.testing_engine() + class MockConnection(Connection): + closed = False + def begin(self): + raise Exception("boom") + + def close(self): + MockConnection.closed = True + engine._connection_cls = MockConnection + fn = self._trans_fn() + assert_raises( + Exception, + engine.begin + ) + assert MockConnection.closed + def test_transaction_engine_ctx_rollback(self): fn = self._trans_rollback_fn() ctx = testing.db.begin()