Transactionality in SCA – Part 2 – Refactoring Interfaces

More than once, customers have asked me:

‘I want to control the transactionality in my Mediation Module so that I can implement a service’s operation with three calls to a JDBC adapter – and I want them all to be tied together – either the whole operation succeeds or fails. How can I do that?’.

Well, as of WebSphere ESB 6.1, this is pretty easy. Just tie together an export of some sort, a mediation flow component, and a JDBC adapter in a Mediation Module, in a global transaction, using the techniques referenced in Part 1 of this series. Then use the new Service Invoke mediation primitive to do three sequential invocations of the JDBC adapter, and Bob’s your uncle.

The result will look something like this:

However, it sometimes gets a bit more complicated.

OK, that’s great. Now we need to implement an operation where three calls to the database need to be bound together into a transaction. However, one subsequent call should sit outside the transaction – if it fails, it shouldn’t affect the other three. How can I do that?

The trick lies in refactoring the interfaces involved. Take the mediation flow component, and conceptually split it into two, componentA and componentB. The export connects to componentA, which connects to componentB, which connects to the JDBC adapter. componentA should also be connected directly to the JDBC adapter. componentA should have the same interface as before. However, you should create a new interface for componentB, which has an operation for each transaction that needs to be bound together (the three calls to the database in our example above).

(the gotcha here is that in a mediation module, you can only have one mediation flow component, so componentB will have to be a Java component)

Here’s the important part: make sure the global transaction boundaries cover componentB and the database only. Do not include componentA or the export.

Now, have the ‘master’ operation in componentA call your new operation on componentB first. Then, have it call the other operation on the JDBC adapter directly (the one that shouldn’t be tied into the transaction).

Your transactional scenario is now set up as requested, and will behave to tie together the first three calls to the database (or whatever else you do in the operation implementation in componentB). It should look like this:

Transactionality in SCA – Part 1 – The Basics

Customers sometimes ask me how they can enable transactionality in their WESB and WPS Modules and Mediation Modules. I normally point them at this article (and this article also has a lot of good material).

There’s a lot of content in both of those, but here are the really salient points:

  • In SCA, you don’t need code to manage your transactions. Instead, you need to define your components and operations appropriately, and then set up various SCA qualifiers to bind components together transactionally, so they operate together in a global transaction.
  • By default, SCA components run in their own local transaction, so the first thing you need to do is identify which components need to be bound together and set their implementation’s SCA Transaction qualifier to True.
  • You also need to identify each component or import that needs to join the global transaction of the upstream component (the component that connects to it), and set the Join Transaction qualifier on its interface to True to join the two transactions together.
  • You may want to make sure the Suspend Transaction qualifier on any references which connect to downstream components is set to False – although this is the default if it is not present. This makes sure the transaction is not broken at this point.

That’s pretty much it, although you may want to look at the two articles above for more information.

I’ll be publishing another article next week on how you can refactor your interfaces to get your transaction boundaries exactly where you want them.

Pattern Validation

In WebSphere ESB, you can do schema validation of messages by setting the validation checkbox on various mediation primitives. Alternatively, you can use code (perhaps in a custom mediation, for example) similar to the following:

BOInstanceValidator boValidator = (BOInstanceValidator) new ServiceManager().locateService("com/ibm/websphere/bo/BOInstanceValidator");

boolean isItValid = boValidator.validate(myDataObject, anEmptyList);

(both of these methods use the same underlying mechanism).

However, there are some limitations to this approach: for example, pattern restrictions aren’t supported on derived types. In that case, you can always do that part of the validation manually, using code such as the following:

boolean valid = java.util.regex.Pattern.matches(myregexpattern, dataObject.getString("myfield"));

Of course, that does require some knowledge of the structure of the Data Object in question and the patterns that apply to it.

Thanks to Kevin Yang and Chris Markes for help with this tip.

SOA Benchmark

Those of you who are interested in performance or benchmarking might be interested to know that the TPC is currently considering an SOA Benchmark proposed by IBM. For more details, see Andrew Spyker’s blog post here.