More and more businesses are adopting microservices. This may be for green field developments where everything can start as a microservice. Or it may be building microservices that need to interact with or leverage existing, typically monolithic applications. Few companies can afford to build completely net new microservice based applications to replace their existing applications. The best alternative is to create new features using microservices and capitalize on the existing application until it can be replaced, in whole or piecemeal.
In this post, I’ll cover a use case where an existing money management application already exists built using Oracle WebLogic Server. While this example will use JAX-RS and JPA, JDBC as well as EJB or JMS based applications can also be integrated by providing a JAX-RS interface to those applications.
Here is a diagram of the sample application that will be covered in this post:
The basic scenario is an existing WebLogic Server JAX-RS JPA based web application that manages account balances and can have funds deposited to or withdrawn from that balance. A new application is being created using microservices that needs to integrate with this existing WebLogic application. These new microservices are written in Java using Helidon. They provide deposit and withdrawal services.
The issue now is how can one ensure that operations such as transferring funds, to or from, the existing application and the new microservices occur atomically? Fundamentally this is a dual write problem where the write to the source account and the destination account must both succeed or both fail. This is where distributed transactions come into the picture. Normally in WebLogic applications, the internal WebLogic Java Transaction Service is used. It provides XA distributed transaction support across multiple resource managers as well as across WebLogic applications deployed in other WebLogic servers. It can also support transactions spread across other application servers when using SOAP based web services with WS-AtomicTransaction and associated protocols. However, managing transactions that span other technologies, such as Helidon or Node.js or when using REST based services requires another solution.
This is where the Oracle Transaction Manager for Microservices (MicroTx) comes into the picture. MicroTx provides an external transaction coordinator for REST based services. Using MicroTx, the existing WebLogic application with some minor configuration change can be integrated with the new Helidon based microservices while ensuring transactional integrity across the participating systems.
With MicroTx, a microservice can start a transaction and call other microservices that should be included in the transaction. This sample application shows one Helidon microservice that is acting as a sort of bank teller. The teller microservice allows a user to request that funds be transferred from one account to another account. However, those accounts may be held in different systems using different frameworks or languages. In this case, one account is provided by the WebLogic application, and the other is a new microservice running in Helidon.
For a JPA based application like the WebLogic sample application for MicroTx, no code changes are required, just some additional configuration to include the MicroTx client library and define a single property.
This diagram shows how filters are used to propagate transaction context from one microservice to another.
Once these configuration changes are made, the application can participate in distributed transactions that are managed by MicroTx.
For the new Helidon teller microservice, which we call the initiator as it’s the one initiating the transaction, all that is required is to include the MicroTx client library and add the @Transactional annotation:
on the method handling the transfer function. This annotation tells MicroTx that this method must be part of a transaction and begins a new transaction if one is not already present. In addition, if the method returns successfully, then the transaction is automatically committed by MicroTx. If the method generates an exception, the transaction is automatically rolled-back.
When the teller microservice makes a REST call to withdraw money from one of the participants, the MicroTx client library filters add headers to the outbound REST request to indicate to the participant that it should participate in the transaction. The incoming filters in the participant then enlist the participant in the transaction by calling the MicroTx coordinator and establish a transaction context in the participant.
Once the teller microservice has decided the transaction should be committed, it returns success which causes the MicroTx library to ask for the transaction to be committed by calling the transaction coordinator. The transaction coordination service then calls back to each of the enlisted participants to ask them to prepare. If that succeeds, it then asks all the participants to commit. If one or more of the participants cannot prepare, or the initiator decides to abort the transaction, the transaction will be rolled-back. Otherwise, the transaction will be committed. The initiator can abort the transaction by throwing an exception.
This overall flow is shown in this diagram:
In the transaction flow depicted above, MicroTx manages the details of distributed transaction processing so that the application developer does not have to. The interactions in green are completely handled by the MicroTx library. From a developer point of view, MicroTx makes this easy. Use an annotation within Helidon, and configuration within WebLogic Server, and MicroTX will manage the distributed transactions for you.
Note that this is a bit different than the way XA transactions are normally handled. In the typical XA transaction manager implementation, the transaction manager has its own connections to the resource manager. Which means the transaction manager needs its own credentials as well as the appropriate client library for the resource manager. To allow the MicroTx transaction manager to support any resource manager, it proxies its requests to the participant, which already has a connection to the resource manager. This makes the MicroTx transaction coordinator largely resource manager agnostic.
Using MicroTx as an external transaction coordinator allows integrating existing WebLogic Applications with new microservices while ensuring data consistency across the participants. The MicroTx libraries make using MicroTx extremely simple with no code changes required in the WebLogic application. In an upcoming blog post, I’ll cover how to include EJB and JMS based WebLogic applications in a MicroTx managed transaction.
I'm currently the Chief Architect for a family of transaction processing products at Oracle including Oracle Tuxedo product family, Oracle Blockchain Platform, and the new Oracle Transaction Manager for Microservices. My main areas of focus are on security, privacy, confidentiality, performance, and scalability. My job is to provide the technical strategy for these products to ensure they meet customer requirements.
Prior to being acquired by Oracle, I was Chief Architect for BEA Tuxedo at BEA Systems, Inc. While at BEA Systems, I was responsible for defining the technical strategy and direction for the Tuxedo product family. I developed the Tuxedo Control for WebLogic Workshop that greatly simplified the usage of Tuxedo services from Workshop based applications. I also received two patents for methods allowing design patterns in a UML modeling tool to control the generation of software artifacts.
During my more than 40 years of software architecture and development experience, I have worked on a wide range of software systems and technology. At Science Applications International I worked on microcoded plasma display systems and command, control, and communication systems for naval applications. As a senior software consultant at Digital Equipment Corporation, I was the New York Area Regional Tools Consultant and also helped develop a multi-language multi-threaded distributed object oriented runtime environment with concurrent garbage collection.