What is transaction management with respect SOA???
Two words with complex level of understanding, Many of us are still not able to understand what is transaction management and how it work, or how can some one control this transaction. Their are many implementation of transaction management based on technologies in which you are implementing it but TRANSACTION MANAGEMENT term remain same for all.
Today we will talk about transaction management in respect of oracle soa...
As per oracle documents, "A transaction is a logical unit of work that contains one or more SQL statements. A transaction is an atomic unit. The effects of all the SQL statements in a transaction can be either all committed (applied to the database) or all rolled back (undone from the database)."
Points to keep in mind when designing transaction management:
1. Commit: Committing a transaction means making permanent the changes performed by the SQL statements within the transaction., You need to analysis when you want to commit.
1. Rollback: Rolling back means undoing any changes to data that have been performed by SQL statements within an uncommitted transaction. Oracle uses undo tablespaces (or rollback segments) to store old values. , You need to analysis when you want to rollback.
Types of transaction: Now when we design transactions, its required to analysis what type of transaction you need to design, Type of transaction always differ and it will always depends on what type of implementation you need for your system.
1. Local: The transaction involved only the single database and all updates made to the database were committed at the end of these changes. This is referred to as a local transaction.
2. Global: A global transaction involves a complicated set of management objects--objects that track all of the objects and databases involved in the transaction. These global transaction objects--TransactionManager and Transaction--track all objects and resources involved in the global transaction. At the end of the transaction, the TransactionManager and Transaction objects ensure that all database changes are atomically committed at the same time.
How to define transactions:Transactions manage changes to multiple databases within a single application as a unit of work. That is, if you have an application that manages data within one or more databases, you can ensure that all changes in all databases are committed at the same time if they are managed within a transaction.
Transactions are described in terms of ACID properties, which are as follows:
· Consistent: the effects of a transaction take the database from one consistent state to another consistent state.
· Durable: when a transaction is completed (committed or rolled back), its effects persist in the database.
Transaction Management in Oracle SOA:
· Multiple DB-Transactions invoked by Oracle BPEL process, where all these DB invocations are related to XA Datasources .
· Multiple DB and Non-DB Transactions invoked by Oracle BPEL Process, where all these transactions are related to heterogeneous applications.
How Oracle SOA BPEL handle transaction: Oracle BPEL Process Manager by default creates a new transaction on a request basis. That is, if a transaction exists, it is suspended, and a new transaction is created. Upon completion of the child (new) transaction, the master (suspended) transaction resumes.
However, if the request is asynchronous (that is, one-way), the transaction is either:
· Inherited for insertion into the dehydration store (table dlv_message).
· Enlisted transparently into the transaction (if one exists).
There is no message loss. Either the invocation message is inserted into the dehydration store for processing or the consumer is notified through a fault.
1. If Service (bpel-process or composite) "A" invokes Service "B", and Service B's transaction participant type = "NEVER" then, Service "B" always runs in its own transaction and never comes under Service "A" transaction.
2. If Service B Transaction participant type = "MANDATORY" then, Service B uses the Service A transaction scope, if Service A transaction is not available then, Service B creates its own transaction.
3. In Service A, if "Idempotent" property at the ServiceB-partner link is set to false, then Service A and Service B runs in different transaction units.
4. Even though Service A and Service B are in agreement to use same transaction, but Service B is not a part of XA Type transaction source then, BPEL-Engineer needs to write the code in Compensation handler to rollback the transactions based on business requirement and fault-handlers.
How to configure transaction in oracle BPEL:
many="false" type="xs:string">required | requiresNew</property>
As earlier we was talking about GLOBAL & LOCAL TRANSACTION, Now their will be a case where
you need to communicate with two systems which are not in XA transaction enable or atomic transaction.
1.System "A" is a type of SOAP service but non-transactional.
2.System "B" is a type of SOAP service but non-transactional.
3.BPEL will orchestrate both A and B, Now when A is done with it's calling, B makes a fault but A already done with it's commit as
they are not in global transaction and creating there own local transaction.
4.How System "A" transaction will rollback.
For such cases, Oracle SOA provide an activity "compensation", Which is used to control/rollback transaction for such cases.
Such implementation are called "Heterogeneous transactions in a single transaction unit".
· The only catch here is, Heterogeneous transactions may involve with flatfiles, XA-Based databases, non XA-Based databases, third party applications, webservices and many more.
· Now the point here is, how we can bring all these applications, transactions, databases bring together as a single transaction unit?
· What is the best way to rollback or commit these XA-based, non-XA Based transactions?
As mentioned in the previous section, bpel-pm commit or rollback only the transactions those are part of that specific "component-trx-context" and part of "XA based datasources".
That means, if any of the application datasource is not an XA Datasource then, it does not comes under the rollback or commit.
In BPEL, "compensation handlers" provides a flexibility to rollback or reverse the transactions for business or/and system exceptions.
Compensation handler functionality is a kind of "catch" block in Java programming language.
Using this compensation handlers, pro-grammatically we can rollback the transactions.
·Usually, bpel engineers, writes the programatic rollback code in "compensation handler" of bpel-scope to reverse the transactions executed of that specific scope.
·"Compensation handlers" are not triggered automatically rather they need to explicitly invoked using "compensate" activity., which can only be invoked from within a fault-handler or another compensation handler.
·When the "compensate" activity (which is invoked from fault-handler of that scope) is executed, it will only invoke the "compensation handlers" of that particular scope associated to that fault-handler.
·If "compensate" activity at process level is invoked then, it will only execute the compensation handlers for the top-level scopes. The compensation handlers will only be invoked for those scopes which have completed successfully and will be invoked in the reverse order of completion. That means, the most recently completed scope's compensation handler is invoked first, and then the next most recent and so on.
·which will automatically calls the code (or activities) included in "compensation handler" associated to this scope.
How to design compensation for your BPEL process:
Compensations consist of 2 parts, the compensation handler, and the compensate activity.
1.Each scope can have one compensation handler
2.A compensation handler defines an undo sequence for the scope it is bound to, for example "cancel flight"
3.A compensation handler can be called directly (by specifying a scope) or indirectly by a compensate activity
The use case: Consider a flow, where a user can pass a data, and the flow will search for / book a flight - and afterwards try to book a hotel room. Given the hotel is not available, the flight should be cancelled.
The solution: As per above definitions the ReserveAirline scope will have a compensation handler attached, that contains the logic for canceling the previously booked flight.
<!-- define a compensation handler -->
<compensationHandler> <!-- call cancel ticked -->
<invoke name="Invoke_CancelTicket" partnerLink="AirlineBookingService" portType="airline:airlineBooking" operation="cancelSeat"/>
<invoke name="Invoke_BookTicket" partnerLink="AirlineBookingService" portType="airline:airlineBooking" operation="reserveSeat"/>
The next step in this little sample happens within the scope, responsible for booking a hotel room ().
The operation to reserve a hotel room (reserveHotel) throws a fault if no room is available for the given dates hotel:NoRoomAvailfault.
<catch faultName="hotel:NoRoomAvailfault" >
<throw name="RollBack" faultName="client:rollBackFault"/>
<invoke name="Invoke_ReserveHotel" partnerLink="hotel" portType="ReservationSystem" operation="bookRoom"/>
In the above code a catch block is defined to catch the specific fault we expect and throws itself a rollBackFault to the parent scope, that will trigger the compensation, we have defined earlier.
The last part is is to define a catch block on the parent scope, that triggers in case of a rollbackFault and fires the compensation defined on the ReserveAirline scope.
<!-- catch the rollback fault and call -->
<compensate name="CompensateBoookings" scope="ReserveAirline"/>