The article is an effort to demonstrate transaction boundaries in Oracle SOA, I will try to demonstrate with BPEL first, later we will see in OSB.
Implementing the process in BPEL
In BPEL, the activities that defines transaction boundaries are Receive, Pick, invoke, wait and checkpoint. So let us demonstrate each of them by some examples.
Usecase 1 (Building the process without defining transaction boundaries)
For the first use case, we have create a simple BPEL process, performs an Insert operation into two tables (Department and Employee), and both have Master- Detail relationship with department Id as a foreign key.
All resources are XA-enabled and the process forms a global transaction
Below is the process flow
Because we don’t have transaction boundaries, the above process automatically make the entire process run in a single XA transaction. If there is a problem with any of the data sources (for example, if a database is down or database constrain), and no exception handler has been defined, the whole transaction will roll back.
I have tested the above process by making job_id null for the Employee table.
The process failed with an error and rollback whole transaction as expected
Usecase 2 (Checkpoint activity)
For this use case, we have extended the above process by adding a checkpoint activity in between Department and Employee invoke process. So as per the definition, the process should commit all the transaction which are prior to checkpoint activity.
Tested the use case by making job_id null for the Employee table.
The process failed with same error and because we have a checkpoint activity in between Department and Employee detail, it has done commit transaction for Department.
Usecase 3 (wait activity)
For this use case, we have replaced checkpoint activity with wait activity in between Department and Employee invoke process. So ideally, it should also have 2 transactions
Here I have added wait for 1 minute (As per the oracle documentation, the transaction will not commit for short waits)
Below diagram shows the implementation steps
Let’s Test the flow
As expected, the process has done a commit for the transaction prior to wait.
Usecase 4 (Invoke activity)
By default, invoke activity will participate in transaction. In order to make Invoke to commit the transaction, we have to set the idempotent property on the target partner link to false. If idempotent is set to false, the invoke activity is dehydrated immediately after execution and recorded in the dehydration store. This will end the initial transaction and start a new transaction. The diagram below shows how this can be implemented
Deploy and test the service with the same payload
The service failed in the Employee detail invoke as expected. But Surprise, it has rollback the entire transaction including Department table transaction.
I have revalidated the idempotent property in the composite, it is set to false as shown below.
Ideally the process should commit the Department transaction (I am using Oracle SOA Suite 12.2.1 for the demo, it seems to have bug for this version because the previous version 12.1.3 worked for this usecase.)
Usecase 5 (Receive activity)
For this usecase, I have create a new Asynchronous process (AsyncHelloWorld) and added an invoke in between Department and Employee detail, below is the process implementation and transaction diagram
This time the process committed department table transaction as expected.
Conclusion
Other than Idempotent usecase, Oracle BPEL Process Manager uses XA transactions to manage that state, and allows XA transactions to extend beyond the boundaries of the active BPEL process.