[ZODB-Dev] Re: [Persistence-sig] "Straw Man" transaction API

Phillip J. Eby pje@telecommunity.com
Wed, 31 Jul 2002 16:07:55 -0400


At 03:54 PM 7/31/02 -0400, Jeremy Hylton wrote:
>>>>>> "PJE" == Phillip J Eby <pje@telecommunity.com> writes:
>
>  PJE> At 08:36 PM 7/29/02 -0400, Jeremy Hylton wrote:
>  >> Last week, I worked out a revised transaction API for user code
>  >> and for data managers.  It's implemented in ZODB4, but is fairly
>  >> preliminary code.  I imagine we'll revise it further, but I'd
>  >> like to describe the changes briefly.
>
>  PJE> I'm not sure if this new API is in relation to the proposals on
>  PJE> this list or not, but I'm curious how this affects a few
>  PJE> things:
>
>  PJE> * The need for participants to join every transaction.  
>
>How would you like this feature to interact with custom policies for
>mapping threads to transaction ids?  If ZODB keeps with its default
>policy, it may be useful for a ZODB Connection (resource manager) to
>join every transaction run by a particular thread.  However, the
>Connection would need to stop joining at some pount.

I'd just like to be able to create a transaction manager that's used for
some set of transactions, and register some set of participants to it.
Nothing fancy, really.  I'll manage my own threading issues entirely
outside of the transaction manager and participants.


>  PJE> * If a data manager can't support rollback to a savepoint, what
>  PJE>   does it return?
>
>Good question.  Here's my first guess at an answer: It returns None.
>If multiple resource managers participate in a transaction and one
>doesn't support savepoints, then the application can't rollback the
>savepoint.  The other resource managers may execute the savepoint, but
>rollback is impossible.

Perhaps it should return a NullSavePoint object, that returns False to a
"can_rollback" method.  The aggregated savepoint object would return true
for can_rollback if all its contents return true, and the rollback() method
would only run if can_rollback is true.


>(In the case of ZODB, it can be useful to execute a savepoint
>regardless of whether it is rollback, because it allows modified
>objects to become ghosts.)

Yes; it could also be used to ensure that an external system such as an SQL
database reflects the current state of persistent objects, which is handy
if one must also use legacy code in the same transaction context which runs
against that data.


>  >> (The need for notify-on-read, BTW, is to support higher isolation
>  >> levels than ZODB currently supports.)
>
>  PJE> And to support delayed loading of attributes by multi-backend
>  PJE> data managers.  Although to support that, there'd need to be
>  PJE> the opportunity to override the attribute value that was read.
>
>It's possible to define a custom __getattr__ on a Persistent
>subclass.  Is that enough?

Nope.  __getattr__ is implemented by the Persistent object, not the data
manager.  I want the *data manager* to do delayed loading of attributes in
certain cases.  For example, it's a common use case for me to need data for
an object from both an LDAP and an SQL database.  However, some LDAP
attributes (such as a user's picture or the membership of an LDAP group)
are *huge*.  I'd like to avoid the overhead of loading these attributes
until/unless they're needed (because on most transactions they're not
needed).  That's why I need the ability for a data manager to implement
delayed loading of certain attributes.

Without this separation, you can't implement your Persistent objects as a
truly abstract application model, that's portable to different data
managers as backends.  A Persistent object should never have to know
details of how its storage is implemented.  In theory, as a result of this
SIG's work, people should be able to write a set of Persistent classes for
any application model, and then persist it with any sufficiently capable
data manager(s).