"Kenneth D. Litwak" wrote:
>
> Ihav e some questions about the EJB spec saying that a container must support
> two-phase commit.  I know what a two-phase commit is. I owned code at IBM to
> do it for DB2/MVS.  What I don't understand is what the term "supports' means
> here.  Since the container isn't a database enginre, what items in a container
> have to vote on doing commit phase 2 during commit phase 1?  What's more, I
> can imagein all kinds of scenarios that essentailly make this notion useless.
> Trans 1 starts (CMT or BMT)
> Session bean method A is called
> Method A calls methods B, C and D of three separate entity beans, which map to
> two separate databases, Sybase and Oracle.
> The database updates are done,method A completes
> The container's TM calls commit on the transaction.
> This causes, I'm assuming, a commit call against both the Oracle and Sybase
> database.  The Sybase update succeeds (I worked there, so I have to tive htem
> some credit).  THe Oracle update fails.  Having th3 container do a two-phase
> commit here is totally irrelevant so far as I can see, since the TM cannot
> rollback the committed changes in the Sybase database.  The transaction can be
> rolled back, which might cau;se a rollback in Oracle, but Sybase is already
> committed.  It's too late.  So what good does it do to have the global
> transaction rolled back in a two-phase, container-level transaction?

Here is a simplified(?) explanation of 2-phase commit...

The essence of 2-phase commit is that each recoverable resource manager (RM),
such as a database, supports 4 special APIs, RM-PREPARE, RM-COMMIT, RM-BACKOUT,
and RM-RESYNCH whose meanings will hopefully become clear later. (BTW, these are
my names for purposes of this simplified explanation). When the application
calls COMMIT this goes to the app server which has been keeping track of which
RMs are involved in the transaction via callbacks from the RM to the app server.
On receiving the COMMIT the app server first calls RM-PREPARE to each RM. RM's
are allowed to reject RM-PREPARE. If any RM does so, the app server issues
RM-BACKOUT to all other RMs. If all RM-PREPAREs succeed the app server calls
RM-COMMIT to each RM.

You will of course realise that this does not (yet) work if there is a system
crash. So how does 2-phase commit solve this problem?

Let's go back to RM-PREPARE. The true meaning of RM-PREPARE is that once an RM
has responded OK to RM-PREPARE it loses its right to make a decision about the
transaction. Between RM-PREPARE and RM-COMMIT (or RM-BACKOUT) the transaction is
"in doubt" as far as that RM is concerned and if there is a crash the RM must
restart with the transaction remaining "in doubt". "Prepared" therefore means
"Prepared to hang about indefinitely if necessary to be told what to do". To
achieve this both the before and after images of the records changed by the
transaction are stored on disk somewhere and this is what the RM does during the
call to RM-PREPARE.

The final piece of the jigsaw then is the RM-RESYNCH API which is used when both
the RM and the App Server are back running again after the crash. The app server
issues RM-RESYNCH to tell the RM which in doubt transactions to commit and which
to back out. The RM is not allowed to refuse to dispose of the transaction in
the way the app server dictates. The app server writes to disk during the
2-phase commit process in order to know the answer this question after a crash.

So the transaction commits if and only if the app server manages to write the
transaction-committed record to disk before the crash.

If that sounds complicated, it's actually much worse - I've oversimplified a lot
in the area of RM-RESYNCH, I've missed out distributed transactions,
optimisation when there is only one RM involved, techniques needed to ensure
that restart is fast, relation to record locking, media recovery from logs,
fuzzy backups, etc. But clearly the app server has an important role in 2-phase
commit.

Ian McCallion
Alexis Systems Limited

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to