[Zope3-Users] Re: FW: ZODB storage ways

j.kartnaller j.kartnaller at robotech.at
Wed Apr 5 11:31:43 EDT 2006


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
>>
> 
> 



More information about the Zope3-users mailing list