[Zope-dev] zope.sqlalchemy locks up transaction

Brian Sutherland brian at vanguardistas.net
Tue Sep 16 03:56:22 EDT 2008


Hi,

I've recently seen a situation where zope.sqlalchemy locked up the
transaction machinery. I'm not sure exactly what happened, but have
attached a failing test for at least one bug which may have caused it.
Hopefully it's self explanatory;)

If someone could help me solve this, that would be great!

-- 
Brian Sutherland
-------------- next part --------------
Index: /Users/jinty/src/zope.sqlalchemy/src/zope/sqlalchemy/tests.py
===================================================================
--- /Users/jinty/src/zope.sqlalchemy/src/zope/sqlalchemy/tests.py	(revision 91170)
+++ /Users/jinty/src/zope.sqlalchemy/src/zope/sqlalchemy/tests.py	(working copy)
@@ -32,6 +32,7 @@
 import sqlalchemy as sa
 from sqlalchemy import orm, sql
 from zope.sqlalchemy import datamanager as tx
+from zope.sqlalchemy import mark_changed
 
 TEST_TWOPHASE = bool(os.environ.get('TEST_TWOPHASE'))
 TEST_DSN = os.environ.get('TEST_DSN', 'sqlite:///:memory:')
@@ -169,6 +170,32 @@
         transaction.abort()
         metadata.drop_all(engine)
 
+    def testAbortAfterCommit(self):
+        # This is a regression test which used to wedge the transaction
+        # machinery when using PorstgreSQL (and perhaps other) connections.
+        # Basically, if a commit failed, there was no way to abort the
+        # transaction. Leaving the transaction wedged.
+        transaction.begin()
+        session = Session()
+        conn = session.connection()
+        # At least PostgresSQL requires a rollback after invalid SQL is executed
+        self.assertRaises(Exception, conn.execute, "BAD SQL SYNTAX")
+        mark_changed(session)
+        try:
+            # Thus we could fail in commit
+            transaction.commit()
+        except:
+            # But abort must succed (and actually rollback the base connection
+            transaction.abort()
+            pass
+        # Or the next transaction the next transaction will not be able to start!
+        transaction.begin()
+        session = Session()
+        conn = session.connection()
+        conn.execute("SELECT 1")
+        mark_changed(session)
+        transaction.commit()
+
     def testSimplePopulation(self):
         session = Session()
         query = session.query(User)


More information about the Zope-Dev mailing list