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

Jeremy Hylton jhylton at gmail.com
Tue Jul 12 10:27:29 EDT 2005


On 7/12/05, Tim Peters <tim at zope.com> wrote:
> [Jeremy Hylton]
> > IIRC, the old implementation of savepoints kept a copy of the index at
> > the time the savepoint was taken so that you could rollback to it
> > multiple times.  I don't think there's any way to avoid such a copy.
> 
> Right, and the current implementation did that too.  The "surprise" was that
> it wasn't enough.  Sketch:
> 
> 1. Modify object 0.
> 2. Make savepoint 1.
>        It makes a copy of the current index, say {0: 0}, and remembers
>        the TmpStore size, say 100.
> 3. Fiddle around.
> 4. Rollback to savepoint 1.
>        This sets the TmpStore index to the saved {0: 0}, and truncatss
>        TmpStore to size 100.  So far so good -- or so it seems.
> 5. Modify object 0 again, and make savepoint 2.
>        This changes the TmpStore index to {0: 100}, makes of a copy of
>        {0: 100} in savepoint 2, and increases TmpStore size to 200.  This
>        just did something horribly wrong too, although it's subtle.
> 6. Rollback to savepoint 1 again.
>        Because a copy of savepoint 1's index wasn't _also_ made in
>        step #4, the index savepoint 1 is holding onto mutated to
>        {0: 100} during step #5 (object sharing).  This (#6) step
>        leaves TmpStore with (the mutated) index {0: 100} and size 100.
> 7. Reference object 0.
>        Oops.  The index tells us to seek to pos 100, but TmpStore has
>        been truncated to 100.  We get a low-level exception from
>        struct.unpack() about not enough bytes to unpack the data record
>        header.
> 
> You can guess that I saw that happening <wink>.  Step #4 also needs to copy
> the index (from the savepoint to TmpStore) instead of sharing a reference,
> although this wasn't needed so long as a savepoint could be "used" at most
> once (then mutating the savepoint's index after a rollback had no ill
> effect, as the savepoint's index could never be referenced again).

I understand.  The further invariant is that the index captured when a
savepoint created is immutable.

Jeremy


More information about the ZODB-Dev mailing list