[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