[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