[Persistence-sig] "Straw Man" transaction API
Sebastien Bigaret
Sebastien.Bigaret@inqual.com
15 Jul 2002 15:06:16 +0200
Ok, now for some comments (with no flamethrowers lighted up, but maybe I'll
trigger some ;)
About the Transaction API:
The API seems globally OK to me I have. I'd like to make the following
remarks:
- about info/setInfo(): maybe we need a setInfo() different from an
updateInfo() or addToInfo(). I also suspect that a 'ResourceManager'
writing info. to other participants might use such a metadictionary to
pass additional information for use in the current transaction (warning:
name collision); if this is *not* the place for that, it should perhaps be
stated in doc.
- registration of Participants:
We might need a unique identifier for a given participant ; e.g., we
might wish that only one participant for a given 'postgresql' DB
connection is registered (in that case, the id. could be the DB backend
name+the connectionDictionary).
Obviously participants could still register without an id.
- revert(): I expected an 'undo()' ; 'revert' sounds like 'abort' to me, but
this can just be a language problem --the documentation made it clear.
- about commit(): I see this basically like a vote_commit() on each
participants, followed by a commit_txn()
I have the feeling that what will be done during the commit() phase should
be explicitly stated, along with the goals we are going after. Here is a
little example: suppose a transaction has to commit changes against two
different DB storages, DB1 which supports multi-phase commit, DB2 which
does not.
Then they get vote_commit(): DB1 will be able to answer OK or KO, but DB2
will not because it is not capable of saying whether a transaction will
successfully succeed, hence: it answers 'OK' to the 'vote_commit' message.
Now the participants gets the commit_txn() ; since we do not assume any
particular ordering for paricipants, suppose that DB1 gets it first. DB1
commits the changes, then DB2 attempts to commit its changes but fails:
what can we do? We can stop committing and start sending 'abort_txn' to
all participants, however, DB1 is likely to be unable to revert the
already committed changes --and this will definitely be the case if both
DB1 and DB2 do not support nested transactions).
My opinion here is that we shouldn't try to handle multi-backends commits
as a whole -- some backends simply makes it almost impossible. But: this
should be clearly stated.
- last on this: it may be useful for observers to get events such as
transaction_did_commit() (committing is a Transaction's message for which
we cannot guarantee it will come to its normal end, for the reasons
written above) ; I'm thinking here of some DB-caches that would be
participants/observers for the Transaction machinery, that would take the
opportunity to update their caches, etc.
About the Participant API:
- I have some problems about the begin/end_savepoint(): again this might be
a language problem, but I would prefer something like
'prepareToSavepoint()' and 'markSavepoint()'
- same for begin_commit()
- vote_for_commit: as far as I understand participants using other
participants can simply ignore it, but should not raise (exception to be
named, BTW). To my understanding, a raise here is understood as a veto.
Is that it?
Last: do we need to specify a TransactionManager or TransactionFactory API?
Some ideas about what could be done there: (hmm, this could be made class
method as well)
- registering participants' factories, so that Transactions can be
initialized with a default set of participants, since applications often
use the same configuration for their Transactions. Something like:
def buildDefaultTransaction(self)
- ???
It seems to me that the points stressed in the sig-charter are taken into
account here --except for the 'Effective Memory Usage' which, by the way,
cannot be addressed at the transaction level --and I do not really see how
this particular point can be made anything else but a ``compulsory
recommendation'' ?!
-- Sebastien.