[ZODB-Dev] Pluggable transactions logic

JohnD.Heintz JohnD.Heintz
Mon, 30 Jul 2001 13:46:10 -0500


On Monday 30 July 2001 12:58, Steve Alexander wrote:
> Chris Withers wrote:
> >  I was anticipating
> > whatever initialises and commits transactions would keep a list of th=
e
> > registered agents (to use my words) and call the appropriate ones, in
> > order, atthe appropriate points.
> >
> > Would that be possible?
> >
> > Would it be a good idea?
>
> What I've sketched out on paper goes something like this:
>
> Products can register that they want to be notified at various points i=
n
> transaction processing.
>
> These points are:
>
>    register      to be notified when an object registers itself with th=
e
>                  transactions machinery

I hadn't thought about extending the Transaction class here.  Interesting=
=2E  I=20
guess that I had wanted to stay out of the code path between=20
Transaction.begin() and Transaction.commit() because of performance reaso=
ns.

However, now that I think about it, the way I am using CommitActivity obj=
ects=20
amounts to pretty much the same thing.  Hmmm.

>
>    pre-commit    this is where indexing agents and rule agents run
>
>    boundary      when a transaction gets commited or aborted
>
>    post-commit   after a transaction is finished
>
> and possibly
>
>    abort         when a transaction aborts

I would expose more detail that just "boundary".  The ZODB Transaction sp=
ilts=20
that into tpc_vote() and tpc_finish() calls.  The primariy difference bet=
ween=20
these is that tpc_vote() can raise an Exception and abort the whole=20
Transaction while tpc_finish() gets ignored.

>
>
> Those are the ones motivited by the use-cases I have so far. There may
> eventually be others.

I think that the distinction between vote and finish is important for=20
integrating external transaction systems with processing during a ZODB=20
Transaction.commit().  We are doing this (and using vote() time processin=
g=20
not finish()) to store the content of some object on the file system inst=
ead=20
of in the ZODB Storage.

>
> A plug-in will register with the ZODB something like this:
>
>
> from ZODB.Transaction import registerPlugIn, PRECOMMIT, NORMAL
>
> registerPlugIn(myMethod, "TransactionAgents indexing and rule agents",
> PRECOMMIT, NORMAL)
>
>
> This says that myMethod will be called every time a transaction is abou=
t
> to start the TPC process.

The TM.py and my own CommitActivity.py allow this kind of processing to=20
happen by hooking into the Transaction as if another ZODB Storage were=20
present.  This means that tpc_begin() will be called on these "plugins" a=
long=20
with the one or more ZODB Storage instances *before any persistent object=
s=20
are written* to the ZODB DB.  One implication is that We never know if we=
=20
will receive a tpc_begin() call before or after the ZODB Storage does.  I=
=20
don't think that this could actually matter, but I is different that codi=
ng a=20
registerBeforeTransactionCommit() callback which I would assume would be =
run=20
before *any* other ZODB code.

>
> I imagine the NORMAL to represent some arbitrary priority, say 100.
> There should be constants for NORMAL, FIRST_PLEASE, and WHENEVER.

In my vision the priorities would all be handled by the "Agent" manger cl=
ass=20
that used Transaction callback registrations to dig into the Transaction=20
commit() process at the various points: begin, vote, finish, abort, and=20
postCommit. [Note: the first four are already built into the ZODB=20
infrastructure.  I have included the last one because we needed it and it=
=20
follows pretty closely.]

>
> I have this image of an add-in to the Zope control panel where you can
> interactively jig around with the ordering of the plug-ins. That's what
> the second descriptive argument of registerPlugIn is. So, the priority
> is kind of advisory. There is an API for application writers to alter
> the order in the ZODB, and a ZMI tool for this when used in Zope.

We definitely need to have this defined lower that Zope.  We are only usi=
ng=20
the ZODB and therefore I'm not even thinking hard about how this would sh=
ow=20
up in Zope.

>
>
> In the current version of TransactionAgents, I've added methods to the
> ZODB Transaction class to register various kinds of agents. I see these
> moving into the a module in the TransactionAgents product, for people t=
o
> import as necessary.
>
> ----
>
> Note to Chris:
>
> In your use-case, how do you see your objects uncataloging themselves?
> When an object gets deleted, it is its parent that gets registered with
> the transaction, not the object. This is because the parent just severs
> the link to the child, and the garbage collector sees to the rest.

Hmmm.  This is interesting - and definitely a different topic than I've b=
een=20
thinking about.  I think the way I would have guessed this to be handled =
was=20
whatever method handled uncatalog would create (probably indirectly) a=20
CommitActivity that handled the logistics of doing/undoing the necessary=20
catalog manipulations.  This probably isn't what you were thinking is it?

>
> I still think you end up with something like ZPatterns' DataSkin class
> to allow an object to know when it has been changed, and how, and
> whether it is being added, deleted or renamed.
>
> --
> Steve Alexander
> Software Engineer
> Cat-Box limited
>
>
> _______________________________________________
> For more information about ZODB, see the ZODB Wiki:
> http://www.zope.org/Wikis/ZODB/
>
> ZODB-Dev mailing list  -  ZODB-Dev@zope.org
> http://lists.zope.org/mailman/listinfo/zodb-dev

--=20
=2E . . . . . . . . . . . . . . . . . . . . . . .

John D. Heintz | Senior Engineer

1016 La Posada Dr. | Suite 240 | Austin TX 78752
T 512.633.1198 | jheintz@isogen.com

w w w . d a t a c h a n n e l . c o m