[Z3-sqlos] RFC: Transaction simplification branch

Brian Sutherland jinty at web.de
Fri Dec 9 04:38:34 CET 2005


On Thu, Dec 08, 2005 at 11:51:16PM -0200, Sidnei da Silva wrote:
> On Fri, Dec 09, 2005 at 02:03:43AM +0100, Brian Sutherland wrote:
> | On Thu, Dec 08, 2005 at 09:42:48PM -0200, Sidnei da Silva wrote:
> | There are 3 un-resolved issues:
> | 
> |  * Why do we expire objects in a successful transaction? I can't think
> |    of a reason why we need to.
> |  * Why is expireSQLObject (the old expired event) so complex???
> |  * expireSQLObeject must never generate any SQL. I'm pretty sure it does...
> 
> I would need to look at those. Off the top of my head, I think we only
> need to expire 'dirty' objects.

me too, and any object that has had syncUpdate called is not dirty. So I
removed the expiring after a successful transaction on my branch.

see below for the resolution of the other issues.

Anyway, I'm ready to unleash this branch on the world, i.e. merge it to
trunk.

Anyone with objections?

> | > 1. changes that are not commited (eg, abort() was called) shouldn't
> | >    live past transaction boundaries. need to be specially carefull
> | >    about changes that stick on the cache. if I recall that's the
> | >    reason syncUpdate was called.
> | 
> | For an aborting transaction this is how it goes now:
> | 
> |     1 sync is not called on any object (this absence is tested)
> |     2 expireSQLObject is called on all dirty SQLObjects
> |     2 if any SQL was generated, rollback is called on the SQL connection
> |       via zope.app.rdb
> 
> Doesn't sync need to be called to fetch the previous values from the
> database? Or just expires is good enough?

Sadly no, Andres went with a magnifying glass through SQLObject and
found that we need to set _SO_createValues as well. We think this is a
SQLObject bug.

There is a now a regression test for it on the branch.

expireSQLObject now looks like this:

def expireSQLObject(obj):
    """Expire the SQLObject.

    Try to make sure none of the data makes it to the next transaction.

    This function should not cause SQL to be sent as it is not defined whether
    the SQL connection will commit before or after this is executed.
    """
    for connection in connCache.values():
        connection.cache.expire(obj.id, obj.__class__)

    # Expire object values. The transaction has either been aborted or
    # committed.
    obj.expire()

    # Calling sync() would commit the changes because expire()
    # doesn't clear _SO_createValues.
    # XXX this is thought to be a workaround for a bug in sqlobject
    # and should hopefully go away soon
    unproxied = removeSecurityProxy(obj)
    unproxied._SO_createValues = {}

-- 
Brian Sutherland

Metropolis - "it's the first movie with a robot. And she's a woman.
              And she's EVIL!!"



More information about the z3-sqlos mailing list