[ZODB-Dev] semantics of _v_ attributes?
Shane Hathaway
shane at hathawaymix.org
Wed Oct 6 09:33:21 EDT 2010
On 10/06/2010 02:52 AM, Chris Withers wrote:
> Hi All,
>
> I'm trying to fix this bug:
> https://bugs.launchpad.net/zope2/+bug/649605
>
> ...and I'm struggling to find documentation on the semantics of _v_
> attributes.
>
> In particular, surely this code:
>
> base._p_activate() # make sure we're not a ghost
> base.__setstate__(state) # change the state
> base._p_changed = True # marke object as dirty
>
> ...should be enough to indicate that all _v_ attributes should be dropped?
No. That code does not update the object in the current ZODB
connection. That code only updates other connections.
> If it isn't, what is the correct way to indicate to Persistent/ZODB that
> all _v_ attribute should be dropped not only for the current object but
> for all occurrences of that object across all connections to the current
> ZODB?
Separate this into two problems. You have to solve both:
1) You need to update the object in the current connection.
2) You need to update the object in all other connections.
#2 is easy. All you have to do is set _p_changed (which is set
automatically whenever you change an attribute) and commit the
transaction; ZODB will reload the object in the other connections.
Reloading removes _v_ attributes.
#1 is more interesting, because ZODB does not normally cause the
connection that changed an object to reload that object. Therefore,
your transaction needs to do something that clears your _v_attributes
manually. For example, "self._v_cache = None". ZODB will not do this
for you.
To summarize, your code should do this:
self.somedata = something # Update all other connections
self._v_cache = None # Update this connection
That's all you have to do.
If you really, really need to clear all _v_ attributes, then do this:
self._p_changed = True
for key in self.__dict__:
if key.startswith('_v_'):
del self.__dict__[key]
Shane
More information about the ZODB-Dev
mailing list