Florent Guillaume wrote:
Brian Sutherland wrote:
On Tue, Apr 04, 2006 at 10:37:57AM +0200, j.kartnaller wrote:
Here is how I automate the commit process :

<code>
from zope.interface import implements

from transaction import manager
from transaction.interfaces import IDataManager, ISynchronizer

from sqlalchemy import objectstore


class AlchemyDataManager(object):
     """Takes care of the transaction process in zope.
     """
     implements(IDataManager)

     def abort(self):
         objectstore.clear()

     def tpc_begin(self, trans):
         pass

     def commit(self, trans):
         pass

     def tpc_vote(self, trans):
         pass

     def tpc_finish(self, trans):
         objectstore.commit()
         objectstore.clear()

Er, just something I learnt the hard way from working on SQLOS, is that
you should send all the SQL over the line in the first phase of the TPC
but save the final "COMMIT" until the last phase.


Actually this code will never be correct if SQLAlchemy doesn't implement two-phase commit. You *have* to have a real vote phase and a commit phase in the actual data manager. Otherwise you'll sometime commit data in SQL even though another data manager, like a connection to a FileStorage, aborts the transaction (in case of conflict error for instance).
You are right.
I already changed this code completely but must verify if it is tpc save or not.

I currently use the engine to enclose everythin in a transaction and use
objectstore.commit() for the first phase.

I'm also not sure where to put the first phase commit :
In commit or in tpc_vote ?

Jürgen

And last time I looked, SQLAlchemy didn't implement TPC (but it's moving fast, this may have changed).

Florent



     def tpc_abort(self, trans):
         objectstore.clear()

     def sortKey(self):
         return str(id(self))


class TransactionSynchronizer:
"""Synchronizer to add a alchemy data manager to the new transaction.

     Let's check that it implements the interface correctly:

         >>> from zope.interface import verify
         >>> synch = CacheSynchronizer()
         >>> verify.verifyObject(ISynchronizer, synch)
         True
     """
     implements(ISynchronizer)

     def afterCompletion(self, transaction):
         pass

     def beforeCompletion(self, transaction):
         pass

     def newTransaction(self, trans):
         trans.join(AlchemyDataManager())

_synch = TransactionSynchronizer()
manager.registerSynch(_synch)

You also copied one of my bugs here;) If you are working in a
threaded environment, the synchronizer needs to be registered
in every thread.

</code>

It automatically commits or aborts as ZODB would do.

I borrowed most of it from SQLOS.

Warning : this code is not tested under all circumstances !

J�rgen
from interfaces import IUser




_______________________________________________
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users

Reply via email to