Jim Fulton wrote: > Romain Slootmaekers wrote: > > > I think you are pretty far off here. You said you saw a read conflict. > No conflict resolution is done for a read conflict. Further, from the very > brief description of your DB class, it doesn't appear to use any objects > that actually try to resolve conflicts. I doubt seriously that this has > anything to do with conflict resolution. It is very doubtful that a > database > error would cause your data to simply disappear without some sort of error, > like a database corruption error or an error about invalid object ids > (dangling > references). Have you considered an application error?
yes, that's the first thing one does: doubt your own code. the object in question is created once, and there is no code to delete it since in that application, it is of no use. The only thing that happens is that we add/moify/delete other object to that rootnode. > > If you still have the data file with the lost data, it should be > possible to > analyze it to figure out what went wrong. In particular, it would be > helpful > to figure out just what transaction made the data go away to figure out > what it > might have been doing. that was exactly the question I was asking in the first place : tools to browse the ZODB, to see where it broke. > It simply causes the transaction with the read conflict to be reexecuted. > Ok, I figured that out by now as well. the read conflict error has indeed nothing to do with our problem. sorry 'bout that... But we found something else: I included a script below that produces a stripped down analogy of our problem. (no zope needed, just ZODB, and you might wanna modify the first line to get it working) The script produces the following output: C:\zope\devel>bin\python.exe \temp\test.py <Foo instance at 008DCAC8> 0 <Foo instance at 008E1280> 0 Traceback (most recent call last): File "\temp\test.py", line 68, in ? get_transaction().commit() File "C:\zope\devel\lib\python\ZODB\Transaction.py", line 234, in commit j.commit(o,self) File "C:\zope\devel\lib\python\ZODB\Connection.py", line 348, in commit s=dbstore(oid,serial,p,version,transaction) File "C:\zope\devel\lib\python\ZODB\FileStorage.py", line 665, in store data=self.tryToResolveConflict(oid, oserial, serial, data) File "C:\zope\devel\lib\python\ZODB\ConflictResolution.py", line 108, in tryTo ResolveConflict resolved=resolve(old, committed, newstate) File "\temp\test.py", line 30, in _p_resolveConflict print savedState['data'].getHello() AttributeError: PersistentReference instance has no attribute 'getHello' The question is: is intended ZODB behaviour or not, and is there a work around ? have fun, Sloot.
swhome=r'C:\zope\devel' import sys sys.path.insert(0, '%s/lib/python' % swhome) sys.path.insert(1, '%s/bin/lib' % swhome) import ZODB from Persistence import Persistent class Dummy(Persistent): def __init__(self): self.hello = "Hello there..." def getHello(self): return self.hello class Foo(Persistent): def __init__(self): self.data = Dummy() self.count = 0 def incCounter(self): self.count += 1 def getCount(self): return self.count def _p_resolveConflict(self, oldState, savedState, newState): print savedState['data'].getHello() print newState['data'].getHello() print oldState['data'].getHello() diffsaved = savedState['count'] - oldState['count'] diffnew = newState['count'] - oldState['count'] newState['count'] = oldState['count'] + diffsaved + diffnew return newState from ZODB import FileStorage, DB storage = FileStorage.FileStorage('/temp/test.fs') db = DB( storage ) # Init van test object conn = db.open() root = conn.root() root['foo'] = Foo() get_transaction().commit() conn.close() conn1 = db.open() root1 = conn1.root() foo1 = root1['foo'] conn2 = db.open() root2 = conn2.root() foo2 = root2['foo'] print foo1, foo1.getCount() print foo2, foo2.getCount() foo1.incCounter() get_transaction().commit() foo2.incCounter() get_transaction().commit() print foo1, foo1.getCount() print foo2, foo2.getCount()