[Zope3-dev] ZopePublication performs auth outside
transaction
Phillip J. Eby
pje@telecommunity.com
Fri, 25 Apr 2003 18:34:17 -0400
At 04:02 PM 4/25/03 -0400, Jeremy Hylton wrote:
>On Fri, 2003-04-25 at 15:19, Phillip J. Eby wrote:
> > There shouldn't BE a "current transaction manager". That's my point. If
> > there is no such thing as a "current" TM, then there is no need to suspend
> > transactions, only to have multiple TM's.
>
> > One alternative is to do away with 'get_transaction()' altogether, and
> > simply require ZODB4 apps to create a transaction manager, and explicitly
> > supply it to the ZODB objects that need it. That's not really going to
> add
> > much code footprint for the simple cases, but it *will* make it abundantly
> > clear how to do anything "advanced" with transactions.
>
>To the contrary, it seems like this adds needless complexity to simple
>applications. I don't want to add features for advanced applications
>that come at the cost of extra complexity for simple applications.
>
>Put another way, removing get_transaction() does not make clear to me
>how to do anything advanced with transactions. I understand how to use
>suspend() and resume(), even in the context of explicit interactions
>with a transaction manager. A TM has a get_transaction() method that
>returns the current transaction. The TM provides coordination for
>independent entites to participate in a single transaction.
Okay, here's a hypothetical spelling of the API:
from transaction import TransactionService
txnSvc = TransactionService()
myDB1 = DB(txnSvc, ...)
myDB2 = DB(txnSvc, ...)
txnSvc.begin()
# do stuff with objects in myDB1 and myDB2
txnSvc.commit()
Now, how is this more complex than calling 'get_transaction()'? The only
way in which it is more complex is that when I use a database (or perhaps
just when I open a connection) I must explicitly pass my 'txnSvc'. That is
the *only* change in the amount of dead-chicken waving that takes
place. The steps are still:
1. import something from the transaction pacakge
2. call it with no arguments
3. call 'begin()' or 'commit()' or abort() on it
All we're adding is a step 2.1: "pass the result to the constructors of any
data managers you intend to use."
>suspend() allows one participant to stop the current activity and start
>a new one, then later restart the previous activity. That seems a
>useful feature.
Code sample #2:
from transaction import TransactionService
txnSvc = TransactionService()
myDB1 = DB(txnSvc, ...)
myDB2 = DB(txnSvc, ...)
txnSvc.begin()
# do stuff with objects in myDB1 and myDB2
# whoops... need to do something else...
t2 = TransactionService()
otherDB = DB(t2, ...)
t2.begin()
# blah blah
t2.commit()
# continue on with what we were doing...
# okay, done
txnSvc.commit()
Notice that this doesn't require any "suspend" or "resume" - this happens
naturally in the code flow.
It occurs to me that perhaps something else goes on with the suspending and
resuming that you've implemented, that I'm not aware of. But I *assume*
that when you suspend or resume a ZODB transaction, you can't just keep
using the same connection objects, because the cache state wouldn't be
valid. So you have to get another connection if you're doing a different
transaction, right? If so, then making transaction-to-database
associations explicit is a big win in my proposed API because it makes it
very visible that you need a connection that's associated with your
subsequent transaction.
What I'm saying, though, is that even if you had made it so that
connections somehow know to set aside their cache and create a new one,
etc., then that's wasteful (from a code complexity and maintenance POV)
compared to just letting the user explicitly manage it, as in the example
above.
The only benefit that having a single TM adds, is the ability to avoid
explicitly telling data managers what transaction they should belong
to. Given that the common use cases favor having few data managers (I
assume most non-Zope ZODB apps use only one!), this is not much
savings. Explicit is better than implicit.
Given that this discussion is now mostly about the API exported from ZODB,
perhaps we should redirect to zodb-dev? Then perhaps also the user
community can give us some indication of their feelings as well. I would
guess though that the interest expressed by many in Shane's "local
transaction" system already indicates that there are other users whose apps
have outgrown the "current transaction" model.