[Zope3-dev] trigger persistence

Jeremy Hylton jeremy@zope.com
Fri, 6 Sep 2002 08:48:00 -0400


>>>>> "SH" == Shane Hathaway <shane@zope.com> writes:

  SH> "self._p_changed = 1" is probably better for another reason
  SH> also: it makes it easier to "grep" for a nasty little bug.  If
  SH> the "self._p_changed = 1" comes after the code that actually
  SH> makes the change, and an exception occurs between the change and
  SH> setting self._p_changed, ZODB may not know that it needs to
  SH> re-load that object when it aborts.  The object could silently
  SH> lose sync with the database.

  SH> I've never seen this actually happen, but I'm sure it'll bite
  SH> someone.  Put "self._p_changed = 1" before the code that makes
  SH> the change, not after.

I think the issue is a little more subtle.  If you have a method that
modifes an object, but does not complete because an uncaught exception
is raised, do you know if the object is in a consistent state?  It may
be best if the object is not marker as modified, because you'd be
storing potentially corrupt state.

If a method gets an unexpected os.error, it may be best to leave the
object's old state alone.

If a method is intended to exit early via an exception, then it makes
sense to set _p_changed first or use a try/finally.  (The former seems
preferable since there is less indentation.)  For example, you write a
method that calls another function that raises KeyError and you want
your method to raise KeyError, too.

The limit of the mark-as-changed-first approach is that you may mark
it as changed earlier, because you expect the KeyError as a
possibility.  But you get an unexpected ValueError along the way, but
are still marked as changed.

Jeremy