Jim Fulton wrote at 2006-10-6 17:04 -0400:
>> Thread-safety is not an issue for read-only data.
>Yes it is. An object that is read-only from a persistence
>point of view isn't read-only at the Python level.
Okay: thread-safety is not an issue for (truely) read-only data.
It is potentially an issue for only partially read-only data
such as read-only only from a persistence point of view.
I agree that we have spoken about a read-only storage such
that they may be thread-safety issues in this context.
>often have other data. Take volatile data as an example.
In fact, they are the only example (if we disregard bugs
modifying non-persistent attributes without informing
the containing persistent object).
But a single example may be enough.
>Or consider object activation and deactivation. If a ghost is
>shared among multiple threads, then __setstate__ could
>be called from separate threads.
But, why should this be a problem? They would install the same
>And of course, there's the possibility that buggy software
>might try to mutate the objects. How would you prevent it?
The special read-only connection with shared cache would raise
an exception instead of joining the transaction.
Of course, other threads might already have been affected
(e.g. in the example above of modifying non-persistent data).
But, bugs can have nasty effects....
>You couldn't wait until commit if there was the possibility that
>other threads might see the errant changes.
In most cases (when an attribute of a persistent object is changed),
we could be able to detect the forbidden modification
before it happens:
The modification goes through "Persistent.__setattr__"
which informs the associated connection which joins the transaction.
Thus, if the connection does not want that its objects are changed,
it raises an exception instead of joining the transaction.
This fails for:
* volatile attributes -- I have no easy solution
* modification of mutable non-persistent data
This would work, too, provided that
obj._p_changed = True
where called *before* the modification.
Calling it before the modification is in principle
necessary (the get the modification thrown away when
the transaction is aborted) but unfortunately, almost
all legacy code does it after the modification.
But, this simple is a bug -- and bugs can have
For more information about ZODB, see the ZODB Wiki:
ZODB-Dev mailing list - ZODB-Dev@zope.org