Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two Phase Commit/Shared Transaction

Tags:

oracle

The scenario is this

We have two applications A and B, both which are running in separate database (Oracle 9i ) transactions

Application A - inserts some data into the database, then calls Application B Application B - inserts some data into the database, related (via foreign keys) to A's data. Returns an "ID" to Application A Application A - uses ID to insert further data, including the ID from B

Now, because these are separate transactions, but both rely on data from each others transactions, we need to commit between the calls to each application. This of course makes it very difficult to rollback if anything goes wrong.

How would you approach this problem, with minimal refactoring of the code. Surely this kind of this is a common problem in the SOA world?

------ Update --------

I have not been able to find anything in Oracle 9i, however Oracle 11g provides DBMS_XA, which does exactly what I was after.

like image 229
Matthew Watson Avatar asked Dec 04 '22 16:12

Matthew Watson


2 Answers

You have three options:

  1. Redesign the application so that you don't have two different processes (both with database connections) writing to the database and roll it into a single app.

  2. Create application C that handles all the database transactions for A and B.

  3. Roll your own two phase commit. Application C acts as the coordinator. C signals A and B to ask if they're ready to commit. A and B do their processing, and respond to C with either a "ready" or a "fail" reply (note that there should be a timeout on C to avoid an infinite wait if one process hangs or dies). If both reply ready then C tells them to commit. Otherwise it sends a rollback signal.

Note that you may run into issues with option 3 if app A is relying on foreign keys from app B (which you didn't state, so this may not be an issue). Oracle's read consistency would probably prevent this from being allowed, since app A's transaction will begin before app B. Just a warning.

like image 68
Zathrus Avatar answered Mar 06 '23 02:03

Zathrus


A few suggestions:

  • Use Compensating transactions. Basically, you make it possible to undo the transaction you did earlier. The hard part is figuring out which transactions to rollback.

  • Commit the data of applications A and B to the database using a flag indicating that it is only temporary. Then, after everything checks out fine, modify the flag to indicate that the data is final. During the night, run a batch job to flush out data that has not been finalized.

like image 29
jan.vdbergh Avatar answered Mar 06 '23 02:03

jan.vdbergh