There are two types of transaction support, XA Transaction support and Local Transaction support. XA transaction support allows a transaction to be managed by a transaction manager external to a resource adapter, whereas, a local transaction support allows an application server to manage resources that are local to the resource adapter.
To ensure two Oracle Database Adapter invokes commit or rollback as a unit, you need to perform the following:
- Both Oracle Database Adapter invokes must be configured to participate in global transactions.
- Both Oracle Database Adapter invokes must participate in the same global transaction.
- The failure of either invoke must cause the global transaction to roll back.
Configuring Oracle Database Adapter for Global Transaction Participation
In the deployment descriptor (weblogic-ra.xml
file), you must set thexADataSourceName
parameter. Additionally, the referenced DataSource must be configured for transaction participation by creating a data source in Oracle WebLogic Server Console.
You must create a data source and choose one of the XA data sources from the list.
Both Invokes in Same Global Transaction
Once both the Oracle Database Adapter invokes participate in global transactions, to commit or rollback as a unit, they must be participating in the same global transaction. In BPEL, this requires the understanding of where the transaction boundaries are, at what points does a checkpoint have to write to the dehydration store, commit the current global transaction, and start a new one.
The transaction boundaries in a BPEL process occur either before a Receive activity or wait activity, or before anonMessage
or pick activity. This may also occur when invoking a synchronous child BPEL process, unless thebpel.config.transaction
property is set on the partnerlink, as shown in the following code sample.
<property name="bpel.config.transaction">required</property>
Otherwise, the parent process is broken into two transactions and the child process runs in its own transaction.
Failure Must Cause Rollback
Finally, even if both Oracle Database Adapter invokes participate in the same global transaction, the failure of either invoke may not cause the global transaction to rollback.
The only cases where a failure can actually cause a global rollback are:
- A Oracle Database Adapter operation that inserts/updates multiple tables as part of one invoke fails after having succeeded in some writes but not others. In this case, the Oracle Database Adapter marks the global transaction as rollback only, because the invoke operation was not atomic and a commit could cause data corruption.
- The invoke retries multiple times in a database down scenario, until the global transaction times out and is rolled back.
- An explicit
bpelx:rollback
fault is thrown from within the BPEL process.
Using the Same Sessions for Both Invokes
GetActiveUnitOfWork
JCA parameter to true to enable using the same sessions or connections for both the Oracle Database Adapter invokes.
GetActiveUnitOfWork
is an advanced JCA property you can set on anyDBInteractionSpec
. It causes the invoke to register itself with the two-phase commit callbacks, and all writes to the database are performed as part of the two-phase commit. By setting this property on any failure, the transaction is automatically rolled back, as there is no way to handle a fault at this late stage. Similarly, the same underlying TopLink session is used for both invokes, meaning if you merge the same object twice, it is inserted/updated once. All merge invokes that setGetActiveUnitOfWork
as true are cumulative.
Transaction/XA Support
To make two Oracle Database Adapter invokes commit or roll back as a unit requires the following: both Oracle Database Adapter invokes must be configured to participate in global transactions, both invokes must participate in the same global transaction, and the failure of either invoke must cause the global transaction to rollback.
Configuring an Oracle Database Adapter for Global Transaction Participation
In the deployment descriptor (weblogic-ra.xml), you must setxADataSourceName
. The matching data source entry must be configured for global transaction participation.
True XA: Two-Phase (XA) Versus One-Phase (Emulated) CommitXA is a two-phase commit protocol, which is more robust than a one-phase commit or emulated protocol. The difference is that with a one-phase protocol, you may very rarely still see message loss or other rollback/commit inconsistency, on the order of one per one thousand generally.
7 comments:
Suppose you have an Oracle SOA Suite 11g BPEL process invoking a couple of Oracle procedures via DBAdapters and calling a web service. The stored procedures do not use autonomous TX's and do not explicitly call commit. The BPEL process itself is executed as a web service. So to get clean rollback of the database writes if the web service call fails you do not have to change ANY default settings, right? The DBAdapter invokes will be idempotent by default and so the whole synch process, from receive to reply, will implicitly be one XA transaction? And everything will be rolled back if the Java web service throws a runitme exception?
You need to make sure that the DBAdapter call is within the transaction boundary of the BPEL.Make sure you have defined property name="bpel.config.transaction" required property
on the PartnerLink level.Otherwise you may see errors like cannot commit in distributed transaction.
But according to the first link, Working with Transaction in Oracle Bpel, BPEL 11g starts (and ends) transactions implicitly. In my case Receive (or Pick) starts a TX and Reply finishes it causing commits. I deleted the "pragma AUTONOMOUS_TRANSACTION" declarations and commit's in STP's and they to commit and rollback just fine. Even without defining bpel.config.transaction for partner links. It's neat.
That is by default, even without bpel.config.transaction for DBAdapter partner links, they seem to participate in the BPEL global TX. And if you set idempotent=false they will start new TX's. According to the same link.
Yes correct...Default value is required even without declaration.The whole point is if a parent starts a transaction then child cannot call commit() method.So to avoid it we need to bring the child to parent level by making it a part of the already existing transaction.By default,the partner link takes part in Global transaction.
I have had great time reading your article. It’s actually quiet awesome, it is surprising how you have learn t to write your feelings and thoughts in so precise manner. It's good really. anonymous transactions
Post a Comment