[Zope-Checkins] CVS: StandaloneZODB/ZODB - BaseStorage.py:1.17.4.1
Barry Warsaw
barry@wooz.org
Wed, 23 Jan 2002 16:40:26 -0500
Update of /cvs-repository/StandaloneZODB/ZODB
In directory cvs.zope.org:/tmp/cvs-serv12050
Modified Files:
Tag: Recovery
BaseStorage.py
Log Message:
copyTransactionsFrom(): This method is broken when copying
transactions that span commitVersion(), abortVersion() or
transactionalUndo(), because these three methods make updates to the
database that cannot be mimicked with a store() call.
We're defining a new API method called recover() that looks a lot like
store() but which has some important differences:
- The `serial' argument to recover() names the serial number of the
/current/ object revision, not the previous one.
- recover() skips various consistency checks that store() performs,
including the checks for ConflictError and VersionLockError. Thus
it believes the data its given, which /must/ be known to be accurate
(or you could end up corrupting your storage). Also, it ought to be
a bit faster since it does less work than store().
- recover() doesn't return anything.
So, when the concrete storage implements the recover() API -- i.e. it
has a `recover' attribute -- copyTransactionsFrom() will use that
instead of store() to copy the transactions. It will still fall back
to using store() if recover() is unavailable, but then ConflictErrors
or VersionLockErrors may be raised.
=== StandaloneZODB/ZODB/BaseStorage.py 1.17 => 1.17.4.1 ===
_ts=None
ok=1
- preindex={}; preget=preindex.get # waaaa
+ preindex={};
+ preget=preindex.get # waaaa
+ # recover() is a new storage API method which has an identical
+ # signature to store() except that it does not return anything.
+ # Semantically, recover() is also identical to store() except that it
+ # doesn't do the ConflictError or VersionLockError consistency
+ # checks. The reason to use recover() over store() in this method is
+ # that store() cannot be used to copy transactions spanning a version
+ # commit or abort, or over transactional undos.
+ #
+ # We'll use recover() if it's available, otherwise we'll fall back to
+ # using store(). However, if we use store, then
+ # copyTransactionsFrom() may fail with VersionLockError or
+ # ConflictError.
+ if hasattr(self, 'recover'):
+ recovering = 1
+ else:
+ recovering = 0
for transaction in other.iterator():
tid=transaction.tid
@@ -252,9 +269,12 @@
for r in transaction:
oid=r.oid
if verbose: print `oid`, r.version, len(r.data)
- pre=preget(oid, None)
- s=self.store(oid, pre, r.data, r.version, transaction)
- preindex[oid]=s
+ if recovering:
+ self.recover(oid, r.serial, r.data, r.version, transaction)
+ else:
+ pre=preget(oid, None)
+ s=self.store(oid, pre, r.data, r.version, transaction)
+ preindex[oid]=s
self.tpc_vote(transaction)
self.tpc_finish(transaction)