[ZODB-Dev] Automating retry management

Nitro nitro at dr-code.org
Tue May 11 07:52:35 EDT 2010


I'm already using custom transaction/savepoint context managers in my  
code. I use them like

with TransactionContext():
     db.root['sp_test'] = 'init'


with SavepointContext():
     db.root['sp_test'] = 'saved'

On of the context managers:

class TransactionContext(object):
     def __init__(self, txn = None):
         if txn is None:
             txn = transaction.get()
         self.txn = txn

     def __enter__(self):
         return self.txn

     def __exit__(self, t, v, tb):
         if t is not None:
             self.txn.abort()
         else:
             self.txn.commit()


Now you could probably extend this to look like

class TransactionContext(object):
     def __init__(self, txn = None, retryCount = 3):
         if txn is None:
             txn = transaction.get()
         self.txn = txn
         self.retryCount = retryCount

     def __enter__(self):
         return self.txn

     def __exit__(self, t, v, tb):
         if t is not None:
             self.txn.abort()
         else:
             for i in range(self.retryCount):
                 try:
                     self.txn.commit()
                 except ConflictError as exc2:
                     exc = exc2
                 else:
                     return
             raise exc

The looping/except part could probably look nicer. Use case looks like:

with TransactionContext(mytransaction, retryCount = 5):
     db.root['sp_test'] = 'init'

Does this look similar to what you were looking for?

-Matthias

For completeness, here's my savepoint manager:

class SavepointContext(object):
     def __enter__(self, txn = None):
         if txn is None:
             txn = transaction.get()
         self.savepoint = txn.savepoint()
         return self.savepoint

     def __exit__(self, type, value, traceback):
         if type is not None:
             self.savepoint.rollback()


More information about the ZODB-Dev mailing list