On Thursday 15 June 2006 15:21, Oleg Broytmann wrote:
> On Thu, Jun 15, 2006 at 02:11:12PM +0300, Dan Pascu wrote:
> > What about the other 2 patches I sent?
> > The one to break some cyclic references
>
>    I am going to test it, but I think I will apply it after 0.7.1.
>
> > and the other to avoid the call to
> > transaction.rollback() from the transaction __del__() method if a
> > transaction was not successfully instantiated (__init__ failed).
>
>    I don't remember if I saw it.

You did because you said the problem was already fixed in svn, but the fix 
in svn was only for an AttributeError exception when accessing 
self._obsolete in __del__(), while the call to rollback still remains.

Basically the issue is here:

class Transaction(object):

    def __init__(self, dbConnection):
        self._obsolete = False
        self._dbConnection = dbConnection
        self._connection = dbConnection.getConnection()
        self._dbConnection._setAutoCommit(self._connection, 0)
        self.cache = CacheSet(cache=dbConnection.doCache)
        self._deletedCache = {}
    ...
    def __del__(self):
        if self._obsolete:
            return
        self.rollback()

Now if it fails in self._connection = dbConnection.getConnection() and 
raises an exception, it will call __del__() which sees self._obsolete as 
False and goes on to rollback() which will raise another exception since 
self._connection doesn't exist.

My patch did mark the transaction as obsolete until the connection was 
actually created, to avoid this (see the attached patch).
You can move the second self._obsolete assignment before the cache 
creation if you think that can be an issue.

>
> Oleg.

-- 
Dan
--- dbconnection.py.orig	2006-06-15 18:35:14.000000000 +0300
+++ dbconnection.py	2006-06-15 18:36:03.000000000 +0300
@@ -784,12 +784,13 @@
 class Transaction(object):
 
     def __init__(self, dbConnection):
-        self._obsolete = False
+        self._obsolete = True
         self._dbConnection = dbConnection
         self._connection = dbConnection.getConnection()
         self._dbConnection._setAutoCommit(self._connection, 0)
         self.cache = CacheSet(cache=dbConnection.doCache)
         self._deletedCache = {}
+        self._obsolete = False
 
     def assertActive(self):
         assert not self._obsolete, "This transaction has already gone through ROLLBACK; begin another transaction"
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to