[ZODB-Dev] Savepoints are invalidated once they are used

Tim Peters tim at zope.com
Mon Jul 11 13:52:25 EDT 2005


[Christian Heimes]
>>>  From my point of view I can't see a reason why the ZODB forbids a
>>> second rolback to the savepoint.

[Jim Fulton]
>> I agree. This should be changed.

[Tim Peters]
> Sounds good to me -- it looks easy, so I'll do it <wink>.

Something subtler than I've been able to figure out yet is going wrong, so I
made a tim-savepoint branch.  All the tests pass, but ...

After my first round of changes, subtxn abort (transaction.abort(1)) tests
failed.  Turned out the code implementing abort(1) relied on that
savepoint.rollback() marked `savepoint` as invalid, and that was easily
repaired (changed abort(1) to explicitly mark the subtxn savepoint as
invalid).  But after thinking about it, I couldn't understand _why_ that
repair was needed (except perhaps as an optimization), and that spawned this
failing code, which doesn't use subtxns:

"""
import ZODB
from ZODB.FileStorage import FileStorage
import transaction
from BTrees.IIBTree import IIBTree

st = FileStorage("blah.fs")
db = ZODB.DB(st)
cn = db.open()
rt = cn.root()

tree = rt['tree'] = IIBTree()
tree[1] = 1
transaction.commit()

tree[1] = 2
sp2 = transaction.savepoint()

tree[1] = 3
sp3 = transaction.savepoint()

tree[1] = 4
assert tree[1] == 4

sp3.rollback()
assert tree[1] == 3

if 1: # turns out this is irrelevant; "if 0" fails the same way
    tree[1] = 4
    assert tree[1] == 4

sp3.rollback()
assert tree[1] == 3, (tree[1], 3)
"""

The second time sp3.rollback() is done, it seems to revert the state all the
way back to the first commit:  tree[1] is back to 1 again.  The same kind of
thing happened under abort(1) if the subtxn savepoint wasn't explicitly
marked as invalid.  Stepping thru it under pdb didn't reveal the cause,
which means I must have stepped over the important parts ... I'll try again
later.



More information about the ZODB-Dev mailing list