[ZODB-Dev] DB.undo for ZODB-based application: ConflictError - serial numbers !=

Mike C. Fletcher mcfletch@rogers.com
Sun, 14 Apr 2002 17:10:25 -0400


Adding undo functionality to a ZODB-(Zope-3x-branch)-based application 
seems like it should be an extremely simple project, but it has been 
sucking up a lot of time in this case.

Here's the relevant code I'm using:

	...commit...
		transaction = get_transaction()
		self.date = now()
		transaction.note( 'description: %s'%(self.description))
		transaction.note( 'date: %s'%(self.date))
		transaction.note( 'forceReindex: %s'%(self.forceReindex))
		transaction.commit()

		# tells all windows to re-display the database
		self.updateWatchers()

	...undo...
	db = APPLICATION.database
	undoInfo = db.undoInfo( 0, sys.maxint )
	if undoInfo:
		ID = undoInfo[0]['id']
		db.undo(ID)
		get_transaction().commit()
		# rebuild external (non-ZODB-hosted indices
		for collection in APPLICATION.GetTables():
			collection.RebuildIndices()
		dispatcher.send( 'Action Completed', APPLICATION, 
action=undoInfo[0]['description'] )


commit seems to run fine (I can exit after the commit, reload the 
database, and the data is all where you'd expect it to be).  However, 
after running undo, any commit which requires re-storing an object 
touched by the undone transaction causes:

Traceback (most recent call last):
   File "p:\conflictsolver\ui\timeline.py", line 672, in OnMouseUpLeft
     self.OnDragFinish( event )
   File "p:\conflictsolver\ui\timeline.py", line 828, in OnDragFinish
     self.OnDragEventSpace(event)
   File "p:\conflictsolver\ui\timeline.py", line 876, in OnDragEventSpace
     undoableaction.UndoableAction(
   File "p:\conflictsolver\undoableaction.py", line 44, in commit
     transaction.commit()
   File 
"C:\bin\lang\py22\lib\site-packages\Transaction\_defaultTransaction.py",
line 235, in commit
     j.commit(o, self)
   File "C:\bin\lang\py22\lib\site-packages\ZODB\Connection.py", line 
413, in com
mit
     self.commit_store(stack.pop(), file, pickler, transaction)
   File "C:\bin\lang\py22\lib\site-packages\ZODB\Connection.py", line 
462, in com
mit_store
     s = self._storage.store(oid, serial, p, self._version, transaction)
   File "C:\bin\lang\py22\lib\site-packages\ZODB\FileStorage.py", line 
666, in st
ore
     serials=(oserial, serial))
ZODB.POSException.ConflictError: database conflict error (oid 
000000000000004b,
serial was 03441422948b4399, now 034414228c3728d5)


(This is with a CVS version of ZODB, Transaction, Persistence, 
Interface, and zLOG from the Zope-3x-branch a few minutes ago (same 
results with a version from a month ago)).


For the only problem I can think of I have no idea how to check for its 
existence:

	v1 = original to which we want to return,
	v2 = version existing in-memory when undo is called
	Somehow v1 isn't replacing v2 when undo is called, as a result, the views 
don't update (since the objects still have the same values), and the 
next time the object is stored, the FileStorage picks up v2's 
un-reverted persistence/storage flags, which tells it there's a problem 
(and it therefore blows up).


Not sure where to start debugging for this, as I don't know what the 
caching system is doing, (or even what it should be doing).  If there 
are other obviously possible problems, would be happy to hear about them 
too.

Suggestions appreciated,
Mike
_______________________________________
   Mike C. Fletcher
   http://members.rogers.com/mcfletch/