Thursday 18 October 2018

SOA Transaction Boundaries – Part 2

Let us continue with adding some more functionality to our base process. Base process has following activities
  • Consume message from JMS queue using XA
  • BPEL component inserts the data into “sourcetbl” table using XA datasource.
  • BPEL component has oneWayDelivery set to “sync” and “transaction” set to required.
  • No catch all branch
  • Throws rollback at the end of bpel flow.
Base process runs everything in a single transaction and the rollback fault rolls back data inserted into table and puts message back in JMS queue.

Hypothetical Requirement

Let us a consider  a hypothetical requirement.
  • After picking up message from JMS queue, BPEL should insert into “sourcetbl” and “targettbl”.
  • Failure during  insertion into tables, should rollback message in JMS queue
  • Record gets inserted into both table or none of the tables. In other words, if insert to “targettbl” fails, “sourcetbl” insert should rollback.
  • If successfully inserted into source and target table, update source table flag with “Y”. if this fails, JMS message ALONE should rollback. Records inserted into source/target table should not rollback.
  • Refer the image below for the required transaction boundaries.
    • Invoke1 and Invoke 2 should be part of separate transaction. They should rollback /commit together.
    • If Invoke3 fails, it shouldn’t affect invoke1/2. It should rollback only Txn 1.

Base process Modification

  • Add another DB adapter to insert into second table. Use XA datasource.
  • Add one more DB adapter to update sourcetable flag with Y. Use XA datasource.
  • Add invoke  activities after the first invoke in the bpel flow. Ensure the variables are initialized in existing or new assign activity.
  • Remove “Throw” activity.
  • Add a catchAll branch. Throw “Remote Fault”.
    • If binding fault is thrown from DbAdapter and a rollback happens, subsequent redelivery of message is rejected by JMS Adapter with error “Resource adapter invoked onReject() without an associated exception.”
    • Refer this  Resource Adapter invoked onReject Error post.
Do we have the required transaction boundaries with above modifications? Let us find out.

Test Scenario 1

Let us deploy and run the process. The process would complete successfully. It would pick message from JMS; insert record into source table; insert record into target table; update source table flag to ‘Y’.

Test Scenario 2

Let us now try to introduce error while inserting into “targettbl”. Provide invalid JNDI for this.
We can see there are no records in Source/Target table. JMS Message is also rolled back. Modify the process to have valid JNDI so that update goes through fine during next test case.

Test Scenario 3

Now, Let us try to introduce error while updating “Flag” to Y in source table. Modify the process, to have invalid JNDI for third Invoke and deploy the process.
Put a message with a new seq number. Seq number 1 is already in DB. Try with 2.
We can see from audit trail that source & target table insert is completed. However, record with seq number 2 doesn’t exist in those table.  Because of error in third invoke , everything has rolled back. Our hypothetical requirement is
If successfully inserted into source and target table, update source table flag with "Y". if this fails, JMS message ALONE should rollback. Records inserted into source/target table should not rollback.
However, in our case, source and target table have also rolled back. The reason is required transaction boundary is not achieved in the bpel structure we have.
We want Invoke1 and Invoke2 to be in a separate transaction. How do we do that?

Defining Transaction Boundary

Unfortunately there is no direct mechanism at Partner Link level to say these partner links should be in different transaction.  If there is only one resource, we can use non-xa, which will not participate in global transaction. However, we have two resources.
As transaction related properties are available only for BPEL component and not for adapters, we need to embed these adapter calls in a bpel component.
Let us modify our bpel process to look like below image.
Add a new BPEL Component to composite.xml. Let us specify “oneWayDeliveryPolicy” as “sync” and “Transaction” as “required”.
New BPEL Component with oneWayDeliveryPolicy as sync & transaction as required
Modify composite.xml to look like below image.
Modified Composite
Call second BPEL component from first. Remove reference of Source/target table inserts from first BPEL component.
Modified First BPEL
Add Invoke activities for source/target table inserts.
Second BPEL Component Details

Testing Modified Process

Verify all JNDIs are correct and deploy the process. Add a message in queue with seq 2. Process should go through fine without any error. Table will contain two records. We will repeat the same test scenarios as before.

Test Scenario 1

Provide Invalid JNDI for “targettbl” insert. Deploy and run the process. Specify seq number as 3.
We would see everything rolled back as required. No records in tables. Message put back in JMS queue.
Put back valid JNDI in “targettbl” insert.

Test Scenario 2

Provide invalid JNDI for updating flag to “Y”.  Deploy and run the process. Specify seq number as 3.
The result is same as above. Everything rolled back. Message put back in queue. Even though we have embeded in another bpel component everything was executed in single transaction. It is because of the setting we had put initially.
oneWayDeliveryPolicy – sync.  This setting makes first BPEL and Second BPEL to execute in same thread.
transaction – required.  This setting makes the second BPEL to join first BPEL’s transaction instead of creating a new transaction. So, instead of creating two transactions, everything was done in single transaction as earlier.

Test Scenario 3

To make second BPEL component to create new transaction, modify  “transaction” property to “requiresNew”. Deploy and run the process. Specify seq number as 4.
This time, the transaction boundaries would have been created the way we wanted it and our hypothetical requirement is satisfied. Records will be committed in Source and Target table. However, update would have failed and it will roll back only the JMS message.

When working with Adapters, SOA doesn’t provide interface to specify transaction parameters at adapter level. We need to  embed those into BPEL components and specify transaction parameters for BPEL component. By specifying values for oneWayDeliveryPolicy and transaction property we can adjust transaction boundaries and achieve desired results.
In the next post, we will see how throwing and handling faults affects transactions.

SOA Transaction Boundaries

We will try to understand the behavior of SOA transaction  boundaries by creating simple BPEL process and gradually adding functionality to it.
At the very basic, every BPEL process executes in the context of a transaction. It either creates a new transaction or joins an existing transaction.
Let us a create BPEL process which consumes message from a JMS Queue.

Environment

Oracle SOA 11.1.1.7.8  on Windows 7 64 bit OS.

DB Table

CREATE TABLE SOURCETBL(SEQ NUMBER NOT NULL,NAME VARCHAR2(20 BYTE),FLAG VARCHAR2(20 BYTE) NOT NULL,EMAIL VARCHAR2(200 BYTE),CONSTRAINT SOURCETBL_PK PRIMARY KEY(SEQ)ENABLE);

CREATE TABLE TARGETTBL(SEQ NUMBER NOT NULL,NAME VARCHAR2(20 BYTE),FLAG VARCHAR2(20 BYTE) NOT NULL,EMAIL VARCHAR2(200 BYTE),CONSTRAINT TARGETTBL_PK PRIMARY KEY(SEQ)ENABLE)

DataSources & JNDI Names


NameDatasource JNDIDBAdapter JNDI
FirstXAjdbc/FirstXAeis/db/FirstXA
SecondXAjdbc/SecondXAeis/db/SecondXA
FirstNonXAjdbc/Firstnonxaeis/db/FirstNonXA
SecondNonXAjdbc/Secondnonxaeis/db/SecondNonXA

JMS Setup

Following JMS resources are used in the examples.
QueueNonXA CFXA CFAdapter XA JNDIAdapter Non XA JNDI
jms/MyQjms/MyQNonCFXAjms/MyQCFXAeis/jms/XAeis/jms/nonXA
Queue is configured with following “Delivery Failure” Options.
Redelivery Delay Override: 10000
RedeliveryLimit: 1
Expiration Policy: Discard

Sample Schema

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns="http://xmlns.oracle.com/ex/emailrec"
 targetNamespace="http://xmlns.oracle.com/ex/emailrec"
 elementFormDefault="qualified">
 <xsd:element name="ERecord" type="ERecordType"/>
 <xsd:complexType name="ERecordType">
 <xsd:sequence>
 <xsd:element name="seq" type="xsd:integer" />
 <xsd:element name="name" type="xsd:string" />
 <xsd:element name="email" type="xsd:string" />
 </xsd:sequence>
 </xsd:complexType>
</xsd:schema>

BPEL Process with JMS Adapter

  • Create a SOA Application.
  • Add JMS Adapter to consume messages based on above schema. Use Non-XA JNDI to start with.
  • Create a BPEL component based on wsdl created as part of above step and wire it with JMS Adapter.
  • In the BPEL process just add an “Empty” activity.
Deploy the process.  Add the following xml message to JMS Queue
<ERecord xmlns="http://xmlns.oracle.com/ex/emailrec">
 <seq>1</seq>
 <name>Krishna</name>
 <email>kri@dom.com</email>
</ERecord>
There is nothing interesting in this base process. A bpel instance would have been created and completed.

Rollback Fault

As part of the bpel flow, let us throw a Rollback fault. Let us see whether our message is rolled back to JMS queue.
Modify BPEL to have a rollback fault (after  the empty activity) and deploy the process.
Add a message to JMS Queue.
Audit trail shows that the transaction was rolled back. However, if we see our JMS queue, our message is not rolled back to the queue.
Is this because we used non-xa?.

Using XA JNDI

Modify the JMS jca file to have XA JNDI instead of non-xa JNDI and redeploy the process. The result is same as before. Transaction would have rolled back , but we don’t see messages back in our queue.
Does it mean the rollback is not doing what it is supposed to do?.
Let us add one more action, inserting into DB table , as part of the BPEL flow.
  • Add a DB Adapter to insert or merge into the table.
  • use XA JNDI
  • Add an invoke before “Throw” to call  DB Insert.
  • Add a assign/transform activity before invoke to initialize variable for DB insert.
Deploy the process and add a message to the queue. Audit trail will show that “DB Insert” was completed successfully and transaction was rolled back.
If we look at the table, there will be no record, which means “rollback” is doing what it is supposed to do. It roll backed the insert. However, the rollback didn’t restore the message back in JMS queue. So, we can conclude, DB Insert happens in a separate transaction and JMS dequeuing happens in a separate transaction.
The above results implies
  • There will be two transactions.
  • JMSAdapter transaction – which gets committed even before BPEL executes
    This is due to the setting async.persist which will put the message in dlv_message table and commit the transaction. BPEL invoker threads will pickup from dlv_message and initiate BPEL, which will run in new transaction.
  • BPEL flow – which runs in new transaction.
When rollback fault is thrown, only Transaction 2 is rolled back(no record in DB Table). However, transaction 1 will be committed. That is the reason, we don’t see the message back in the queue. So,if we use “aysnc.persist” for “oneWayDeliveryPolicy”, Bpel Engine will execute activities in two transactions as shown in above diagram.

Single Transaction

If we want one transaction instead of two, we need to set “oneWayDeliveryPolicy” to sync.With this setting . DLV_Message table is not used. JMSAdapter and BPEL will get executed in the same thread.
Change “oneWayDeliveryPolicy” to “sync”. Redeploy the process and add a message to Queue.
This time, because of rollback fault, you can find that message is rolled back to JMS queue and retried.
Actually, with this setting also, it will be still two transactions as shown in below diagram.
The reason for above behavior is BPEL always starts new transaction. If there is any existing transaction, it suspends that one. Suspended transaction will resume after the current bpel flow completes.
JMSAdapter Transaction (Txn 1) will be suspended and BPEL starts a new transaction (Txn 2) to execute BPEL activities. When Rollback fault is thrown, Txn2 is rolled back. JMSAdapter gets a remote fault and since it doesn’t handle the fault, Txn 1 also will be rolled back.  We can observe these faults in audit trail
To make BPEL to participate in existing transaction, instead of creating new one (which is default behaviour), we need to set “bpel.config.transaction” property to “required”.
If value is “required”, BPEL will participate in existing transaction , if any available. If not it will start a new transaction.
If value is “requiresNew” (default value), BPEL will create new transaction. If any existing transaction is available, that will be suspended.
Add “bpel.config.transaction” property to composite.xml with value “required” and deploy the process.
 <component name="SoaTxBPEL" version="2.0">
 <implementation.bpel src="SoaTxBPEL.bpel"/>
 <property name="bpel.config.transaction" type="xs:string" many="false">required</property>
 <property name="bpel.config.oneWayDeliveryPolicy" type="xs:string" many="false">sync</property>
 </component>
With this setting , Txn boundary will be like below and everything will get executed in single transaction.
When everything happens in a single transaction, and a rollback fault is thrown, we can not catch it inside bpel , even if we have a catch block.
Modify BPEL process to have a catch all and deploy it. In Audit trail we can see that though a “rollback” fault was thrown and catchall block exists, catchall branch doesn’t get executed.  BPEL fault handling, as with other activities, happens in the context of transaction. When the existing only transaction is rolled back, BPEL will not be able to catch or handle faults.
In all these, we haven’t seen single record getting committed in the DB. If we want to commit the DB transaction and at the same time, we need to roll back messages in queue, we need to move DB Insert out of transaction . Use Non-XA JNDI for DB Insert. This will ensure DB Insert operation doesn’t participate in distributed transaction and gets committed irrespective of rollback fault.
As part of this post we saw how Transaction boundaries are determined when JMSAdapter and BPEL components are used and how values of bpel.config.oneWayDeliveryPolicy, bpel.config.transaction influences boundary demarcation.  In next post (SOA Transaction Boundaries – Part 2), we will see how these values influence transaction boundaries when two bpel components are used.

SOA 12c : How to rollback transaction in BPEL

There are scenarios when we want to complete commit or complete rollback.
This is known as transaction handling.
To demonstrate this scenario I am taking following use case.

Use Case : Read a file and insert data into Header and Line tables. Data must be inserted into both the tables or it should be complete roll back in case of any exception.

Lets start the use case :

1. Drag a file adapter in the Exposed Services. Configure it to read a file from Local directory.


2. Configure two database adapters to insert data into header and line tables.
3. Create a BPEL process and wire it to the FTP adapter and database adapter. After wiring it your composite should look like as below :





















4. Add invoke activity and other assign activity to complete BPEL process. Deploy the service to em console.



















5. For handling transactions you must use a XA datasource. You can create a XA datasource using admin console.

6.  There are two cases for transaction handling.
First Case :

If you are not using catch all, transaction will automatically rollback in case of any exception. In the below example first we will insert data in Header_Details table after that we will try to insert a string value for a column of number type in Line_Details table. It will throw an exception and complete transaction will be rollback.






















Since the transaction was rolled back, it should not insert date Header_Details table and Line_Details table.

























Second Case :

If you are using a catch all, then transaction will not be rolled back automatically in case of any exception. Add a catch all activity in the BPEL service.

BPEL Activity :



















Run the service :























Here transaction was not rolled back, even the BPEL process has been completed.
Let see entries in database tables :































From the above screen shots we can see the transaction was not rolled back. It has inserted data into Header_Details table. But as per our requirement it should not happen. To resolve this issue, you need to use a rethrow activity at the end of your catch all block. In this way control will go back to BPEL and it will handle transaction.


















Run the service :






















The transaction was rolled back, lets see the table entries.











Transactions in SOA

Transactions
  • Services can be:
    • Non-Transactional Services
    • Transactional Service
  • Non-Transactional services are the services that does not modify data.
E.g. File Adapter, FTP Adapter
  • Transactional service can be defined as any service that performs DML operations, where each operation are subject to ACID(Atomicity, Consistency, Isolation, Durability) principles.
  • Transactional services are implemented as a java web services or adapter services which are invoked from SOA using BPEL or Mediator
  • Transactional boundaries depend on context, configurations and environment of the services that are implemented and invoked.
  • Transactional semantics differs for the services that are invoked synchronously compared with services invoked asynchronously.
Transaction Boundaries
  • Transaction boundaries depends on the type of interaction
    • Starts when a service is invoked(operation begins) and Ends when a service ends(operation completes)
    • Propagates across synchronous services which can:
Joining an existing transaction (By default it will Join in Global Tx)
End the existing transaction(Can be achieved by Dehydration)
Propagate the transaction to another synchronous services
    1. Terminate when invoking an asynchronous service, which:
      Ends or suspends the existing transaction
      Starts new independent transaction
Transactional Service Implementation
Services with transactional behavior can be implemented using
  • Web services(i.e. JWS, Spring Web services, ADF-BC) that execute SQL transactions
  • Database Adapter
  • Service Data Objects
BPEL Transaction
  • BPEL processes are:
    • Transient, when they don’t have any dehydration points i.e. execute start to end without dehydration
    • Durable, when one or more dehydration points occur during execution
  • BPEL Transactions are:
    • Begin at the start of the process. The first activity(Receive / Pick) marks the start of the bpel process.
    • Ends at the end of the transient(Synchronous) process, when it send the reply to its client, or when the dehydration point occurs in a durable(asynchronous) process.
    • If the a fault occurs before these end conditions, the transaction is rolled back to the start and unhandled faults are returned to caller.
BPEL Transactional Behavior
  • JTA (Java Transaction API) is used with the request and when:
    • If exists, the local transaction joins the global JTA transaction when transaction property is set.
    • If does not exist then new transaction is started
  • A transaction is completed when it encounters a break point activity(causing dehydration) or reaching end of flow.
BPEL Transaction and Delivery properties
Transaction boundaries between different BPEL services are controlled by 2 properties i.e. Delivery Property and Transaction property
Delivery property can have 3 values. Those are 1)- async.persit  2)- async.cache 3)- sync
Transaction property can have 2 values. 1)- Required 2)- Requires New
<component name=”TransactionBpel” version=”2.0″>
<implementation.bpel src=”BPELASynchCall.bpel”/>
<property name=”bpel.config.transaction” type=”xs:string” many=”false”>required</property>
<property name=”bpel.config.oneWayDeliveryPolicy” type=”xs:string” many=”false”>async.persist</property>
</component>
case1: If BPEL Process is Async or one-way process then, Delivery property is used
async.persit: Delivery messages are persisted in the database in table dlv_message. With this setting, reliability is obtained with some performance impact on the database.
When the client initiates a process instance, an invocation request is placed in an internal queue. Inside Oracle BPEL Server, a message-driven bean (MDB), WorkerBean, monitors the queue for invocation requests. When a message is dequeued, Oracle BPEL Server allocates a thread to process the message.
async.cache : Incoming delivery messages are kept only in the in-memory cache. If performance is preferred over reliability, this setting should be considered.
Message are not dehydrated into dlv_message table. Rest all is same as async.persist.
sync : Directs Oracle BPEL Server to bypass the scheduling of messages in the invoke queue, and invokes the BPEL instance synchronously. In some cases this setting can improve database performance.
case2: If BPEL Process is Sync process then, transaction boundary between client and bpel process is controlled by “Transaction” property
Required : This makes the BPEL process execute as part of the calling transaction. If no calling transaction exists, it will create a new one.
RequiresNew: This is the default value and makes the BPEL process execute as a separate transaction. Any existing transaction will be suspended.
Adapters
  • Transactional adapters that supports Two Phase commit:
    • DB Adapter
    • JMS Adapter
    • AQ Adapter
    • Oracle Apps Adapter
  • Non transactional adapters
    • File Adapter
    • FTP Adapter
Compensation Activity
  • Problem: Transactions do not work with asynchronous services.
    • ACID principles and XA transactions cannot be applied across asynchronous invocations
    • Transactions can be managed for synchronous services, provided all invocations are synchronous.
  • Solution: Compensation handling, which enables an asynchronous invocation to execute:
    • An operation that performs a transaction
    • An operation that perform reverse of previously completed transaction.

Wednesday 17 October 2018

SOA12c -Service Bus Resequencer

We often come under such situation when we receive message from source system which are not in proper sequence but target system need to receive that in proper sequence. To resolve this we need to re-sequence the messages and process them in proper sequence.   Re-sequencing is term used when we need to process incoming messages in sequence which are not coming in proper sequence. Design and developer need to think on this re-sequencing when they encounter such requirement as e described above. E.g. suppose we are receiving sales orders from source system, sales order contain one field with the name sales order number, suppose source system sends sales order in this sequence ( 1, 4,3,2,5,6,7 ) but target system need sales order in this sequence (1,2,3,4,5,6,7) , in this case we need to do re-sequencing of message.

In 11g version of Oracle SOA Suite, re-sequencing was there in Mediator component but this feature was not available for BPEL and Service Bus. In 12c release, this feature is provided for service bus. We can set this feature either at pipeline level or at operation level. In this post, we will discuss on that. We will only discuss about pipeline level re-sequencer.  

We have three types of re-sequencing in Service Bus.

Standard:  This sequencer is used when incoming message contain numeric identifier.  This numeric identifier is termed as Sequence Id. We may specify message Group also, that means incoming order can be Sales Order or purchase order, in this case we will have separate group for both Sales Order and purchase order. When source system send out of order messages then it store out-of-order message until complete order is received this is based on sequence Id.

FIFO: This sequencer works based on message arrival time. Whichever message received first, will be processed first. Here you need to specify only Group. So all the messages which are there in one group processed based on message receive time.

Best Effort: It is used when we receive large number of messages in a short period of time and cannot provide information to the re-sequencer about the identifier to use for sequencing. Typically, the identifier used for sequencing in such scenarios is of a dateTime type or numeric type.

To configure re-sequencer in service bus, double click on the pipeline and choose configuration tab. Click on resequencer, to enable the resequencer check the “Enable Resequencer” checkbox. Once you enable the resequencer, you need to choose the resequencer level. Resequencer level can be set either pipeline or operation. Also choose the type of resequencer which you need to use.

Service Bus Resequencer


If you choose to use standard resequencer then you need to provide values for sequence id and group. Only sequence id is mandatory for you can skip group for this sequencer, empty group value means all the incoming messages will be in one group only.  Sequence id is of numeric type. You can also set resequencer start counter and increment counter. We can also specify message expiry time by setting Timeout value. When we set Timeout as 0, that means messages will never expire.

Standard Resequencer


For FIFO, we need to set only Group and that is also option. So when we choose FIFO resequencer, all the messages are processed based on their arrival time.

FIFO Resequencer

SOA Suite 12c - Thread Pool Changes and Tuning

In SOA Suite 12c, the model for managing and tuning thread pools has been changed significantly from 11g. In 11g, each of the service engines such as BPEL, BPMN and Mediator had their own configurations through Enterprise Manager to tune their respective thread pools.  In BPEL for example, you could configure the invoke threads, engine threads, and system threads. You were not, however, able to control the number of incoming requests to exposed SOAP services for example because these were handled by standard Weblogic execute threads and not the invoke or engine threads.
In 12c, Oracle has moved away from these custom thread pools to use standard Weblogic Work Managers. This allows the thread pools to be managed and monitored in a much more consistent and standard manner. They have also added a Work Manager for incoming requests so that these can be limited and not be allowed to over load the server. Another benefit in SOA 12c is that, by default, the constraints on the Work Managers are matched to the SOADataSource automatically so that you don't have to worry about threads running out of database connections.
As you can see below, SOA now has a large set of Work Managers and minimum thread constraints all beginning with the default_ prefix as well as several Work Managers, thread constraints, and request classes all beginning with the SOA prefix. The default configuration has each default_ Work Manager configured to use its corresponding minimum thread constraint and the SOAInternalProcessing_maxThreads constraint. The SOA_Request_WM Work Manager likewise uses the SOAIncomingRequests_maxThreads constraint for handling incoming Web Service requests.
By default the SOADataSource is set to a maximum of 50 connections. Also by default 20% of this is allocated to incoming requests, 50% to internal processing and 30% to internal buffer. As you can see below, this results in the SOAIncomingRequests_maxThreads being set to 10 threads and the SOAInternalProcessing_maxThreads set to 25 threads.
Now we will change the maximum size of the SOADataSource from 50 to 100 as shown below.
If we check the max thread constraints again, we will see if they have been increased automatically to 20 and 50 respectively.
We can also easily change the ratio of threads in the different constraints as well. If we go to EM, right click on soa-info, go to SOA Adminstration -> Common Properties and then click on the More SOA Infra Advanced Configuration Properties link:
We can then click on the SOAMaxThreadsConfig MBean
From here, we can see three configuration values where we can adjust the ratio between incoming, processing, and buffer threads.  Below I have adjusted it to 40% incoming, 30% buffer and 30% processing.
Within a few seconds, we can see that our max thread constraints have already been updated based on these new ratios:
By implementing these new features, the process of tuning has become much simpler for many of our customers. In most cases, the default settings will work and, if needed, only the size of the SOADatasource or the ratio of the thread pool sizes will need to be adjusted. Only in more specific cases will more advanced tuning, such as creationg additional max thread constraints or fair share request classes, need to be performed. The first step should always be to tune using basic configurations and only move to more advanced configurations when necessary.

xslt padding with characters call template for left pad and right pad

  Could a call-template be written that took two parameters ?   a string, and a   number) return the string with empty spaces appended t...