[ZODB-Dev] Inconsistent use of ConflictError
Greg Ward
gward@mems-exchange.org
Thu, 16 Aug 2001 15:42:00 -0400
--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On 16 August 2001, I said:
> Preliminary patch forthcoming...
OK, I'm attaching three patches to this message:
POSException.patch bulks out the ConflictError class and adds
ReadConflictError
ZODB.patch fixes Connection.py and ZODB/*Storage.py
to raise ConflictError "correctly"
bsddb3Storage.patch fixes bsddb3Storage/bsddb3Storage/*Storage.py
similarly
This is *COMPLETELY UNTESTED*. I need to get back to work, but I wanted
to post this while it's fresh. Plus some feedback would be nice.
Oops, I forgot to try to figure out which conflicts are read conflicts
-- so ReadConflictError is currently unused. That needs fixing.
Greg
--
Greg Ward - software developer gward@mems-exchange.org
MEMS Exchange http://www.mems-exchange.org
--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="POSException.patch"
Index: POSException.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/ZODB/POSException.py,v
retrieving revision 1.7
diff -u -1 -r1.7 POSException.py
--- POSException.py 12 Apr 2001 20:47:00 -0000 1.7
+++ POSException.py 16 Aug 2001 19:36:43 -0000
@@ -102,6 +102,77 @@
class ConflictError(TransactionError):
- """Two transactions tried to modify the same object at once
+ """Two transactions tried to modify the same object at once. This
+ transaction should be resubmitted.
- This transaction should be resubmitted.
+ Instance attributes:
+ oid : string
+ the OID (8-byte packed string) of the object in conflict
+ class_name : string
+ the fully-qualified name of that object's class
+ message : string
+ a human-readable explanation of the error
+ serials : (string, string)
+ a pair of 8-byte packed strings; these are the serial numbers
+ (old and new) of the object in conflict. (Serial numbers are
+ closely related [equal?] to transaction IDs; a ConflictError may
+ be triggered by a serial number mismatch.)
"""
+
+ def __init__(self, message=None, object=None, serials=None):
+ if message is None:
+ self.message = "database conflict error"
+ else:
+ self.message = message
+
+ if object is not None:
+ self.oid = object._p_oid
+ klass = object.__class__
+ self.class_name = klass.__module__ + "." + klass.__name__
+ else:
+ self.oid = self.class_name = None
+
+ self.oid = oid
+ self.class_name = class_name
+ self.serials = serials
+
+ def __str__(self):
+ extras = []
+ if self.oid:
+ extras.append("oid %016x" % utils.U64(self.oid))
+ if self.class_name:
+ extras.append("class %s" % self.class_name)
+ if self.serials:
+ extras.append("serial was %016x, now %016x" %
+ map(utils.U64, self.serials))
+ if extras:
+ return "%s (%s)" % (self.message, ", ".join(extras))
+ else:
+ return self.message
+
+ def get_oid(self):
+ return self.oid
+
+ def get_class_name(self):
+ return self.class_name
+
+ def get_old_serial(self):
+ return self.serials[0]
+
+ def get_new_serial(self):
+ return self.serials[1]
+
+ def get_serials(self):
+ return self.serials
+
+
+class ReadConflictError(ConflictError):
+ """A conflict detected at read time -- attempt to read an object
+ that has changed in another transaction (eg. another thread
+ or process).
+ """
+ def __init__(self, message=None, object=None, serials=None):
+ if message is None:
+ message = "database read conflict error"
+ ConflictError.__init__(self, message=message, object=object,
+ serials=serials)
+
--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ZODB.patch"
Index: Connection.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/ZODB/Connection.py,v
retrieving revision 1.58
diff -u -1 -r1.58 Connection.py
--- Connection.py 4 Jun 2001 12:34:57 -0000 1.58
+++ Connection.py 16 Aug 2001 19:37:32 -0000
@@ -323,3 +323,3 @@
):
- raise ConflictError, `oid`
+ raise ConflictError(object=object)
self._invalidating.append(oid)
@@ -390,3 +390,3 @@
):
- raise ConflictError, `oid`
+ raise ConflictError(object=object)
self._invalidating.append(oid)
@@ -534,3 +534,3 @@
get_transaction().register(self)
- raise ConflictError(`oid`, `object.__class__`)
+ raise ConflictError(object=object)
invalid=1
@@ -559,3 +559,3 @@
get_transaction().register(self)
- raise ConflictError(`oid`, `object.__class__`)
+ raise ConflictError(object=object)
@@ -619,3 +619,3 @@
if self._invalid(None): # Some nitwit invalidated everything!
- raise ConflictError, "transaction already invalidated"
+ raise ConflictError("transaction already invalidated")
self._invalidating=[]
Index: DemoStorage.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/ZODB/DemoStorage.py,v
retrieving revision 1.6
diff -u -1 -r1.6 DemoStorage.py
--- DemoStorage.py 20 Feb 2001 15:00:07 -0000 1.6
+++ DemoStorage.py 16 Aug 2001 19:37:32 -0000
@@ -297,3 +297,4 @@
- if serial != oserial: raise POSException.ConflictError
+ if serial != oserial:
+ raise POSException.ConflictError(serials=(oserial, serial))
Index: FileStorage.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/ZODB/FileStorage.py,v
retrieving revision 1.62
diff -u -1 -r1.62 FileStorage.py
--- FileStorage.py 19 Jul 2001 12:03:43 -0000 1.62
+++ FileStorage.py 16 Aug 2001 19:37:33 -0000
@@ -662,4 +662,4 @@
if not data:
- raise POSException.ConflictError, (
- serial, oserial)
+ raise POSException.ConflictError(
+ serials=(oserial, serial))
else:
Index: MappingStorage.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/ZODB/MappingStorage.py,v
retrieving revision 1.3
diff -u -1 -r1.3 MappingStorage.py
--- MappingStorage.py 11 Jul 1999 21:51:42 -0000 1.3
+++ MappingStorage.py 16 Aug 2001 19:37:33 -0000
@@ -210,3 +210,4 @@
oserial=old[:8]
- if serial != oserial: raise POSException.ConflictError
+ if serial != oserial:
+ raise POSException.ConflictError(serials=(oserial, serial))
--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="bsddb3Storage.patch"
Index: Full.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/bsddb3Storage/bsddb3Storage/Full.py,v
retrieving revision 1.29
diff -u -1 -r1.29 Full.py
--- Full.py 9 Jul 2001 18:38:42 -0000 1.29
+++ Full.py 16 Aug 2001 19:37:54 -0000
@@ -573,4 +573,3 @@
raise POSException.ConflictError(
- 'serial number mismatch (was: %s, has: %s)' %
- (utils.U64(oserial), utils.U64(serial)))
+ serials=(oserial, serial))
# Do we already know about this version? If not, we need to
Index: Minimal.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/bsddb3Storage/bsddb3Storage/Minimal.py,v
retrieving revision 1.9
diff -u -1 -r1.9 Minimal.py
--- Minimal.py 27 Apr 2001 23:28:59 -0000 1.9
+++ Minimal.py 16 Aug 2001 19:37:54 -0000
@@ -178,4 +178,3 @@
raise POSException.ConflictError(
- 'serial number mismatch (was: %s, has: %s)' %
- (utils.U64(oserial), utils.U64(serial)))
+ serials=(oserial, serial))
# Our serial number is updated in BaseStorage's tpc_begin() call,
Index: MinimalReplicated.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/bsddb3Storage/bsddb3Storage/MinimalReplicated.py,v
retrieving revision 1.1
diff -u -1 -r1.1 MinimalReplicated.py
--- MinimalReplicated.py 9 Nov 2000 16:47:31 -0000 1.1
+++ MinimalReplicated.py 16 Aug 2001 19:37:54 -0000
@@ -30,3 +30,4 @@
oserial=self._index[oid]
- if serial != oserial: raise POSException.ConflictError
+ if serial != oserial:
+ raise POSException.ConflictError(serials=(oserial, serial))
Index: Packless.py
===================================================================
RCS file: /cvs-repository/StandaloneZODB/bsddb3Storage/bsddb3Storage/Packless.py,v
retrieving revision 1.5
diff -u -1 -r1.5 Packless.py
--- Packless.py 27 Mar 2001 21:26:16 -0000 1.5
+++ Packless.py 16 Aug 2001 19:37:54 -0000
@@ -157,3 +157,4 @@
oserial=self._index[oid]
- if serial != oserial: raise POSException.ConflictError
+ if serial != oserial:
+ raise POSException.ConflictError(serials=(oserial, serial))
--SLDf9lqlvOQaIe6s--