contributors: Shane Hathaway, Dieter Maurer, Toby Dickenson, Tim Peters
A "volatile attribute" is an attribute of a persistent object whose name
begins with _v_. ZODB does not store volatile attributes: they're
not included in the stored pickle, and other connections to the same
database don't see them. Setting a _v_ attribute on a persistent object
does not mark the object as changed. In effect, volatile attributes
act as non-persistent, in-memory caches, local to a connection.
The lifetime of a volatile attribute is unpredictable. In theory,
a _v_ attribute may be destroyed at any time, and no promises are
made beyond that. In practice, implementations of ZODB to date
destroy volatile attributes only when unloading objects (see
UnloadingObjects). Note that a volatile attribute may live beyond the
duration of a transaction.
It's safe to compute something involving only one ZODB object and store the result as a volatile attribute of that same object, because changes by other connections will cause the object to be unloaded, automatically destroying the volatile attribute. However, if the computation is based on the state of other objects, there is a good chance the volatile attribute's value will fall out of sync with the state of the other objects. If an application needs to cache a value that depends on multiple objects, it should provide its own mechanisms for keeping that value in sync.
Volatile attributes can be useful when a program needs to perform an expensive computation based on the state of a single ZODB object. For example, before a Zope page template executes, it must be parsed and compiled into a series of bytecodes. To do this on every request would be expensive. The page template could store the bytecode, but page template bytecode often contains objects that cannot be pickled. Storing the compiled bytecode in a volatile attribute is an effective way to avoid repeated recompiling, but the code must be prepared to recreate the bytecode whenever the volatile attribute vanishes.
Do not use when... --efge, 2004/07/12 09:27 EST reply
This means that volatile attributes should not be used as caches for data that depends on something
other than the current object (because they'll fall out of sync). Also the fact that they are
thread-specific means that it's very difficult to invalidate such cases anyway (you can't easily
clear volatile attributes of the same object used in another connection). So appart from the use
case described above, they really shouldn't be used.