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