[Zope3-Users] Re: FW: ZODB storage ways
Florent Guillaume
fg at nuxeo.com
Wed Apr 5 10:27:44 EDT 2006
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).
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
>
--
Florent Guillaume, Nuxeo (Paris, France) Director of R&D
+33 1 40 33 71 59 http://nuxeo.com fg at nuxeo.com
More information about the Zope3-users
mailing list