LIGHT

  • News
  • Docs
  • Community
  • Reddit
  • GitHub

Transaction Management

Transaction management in microservices architecture

In traditional monolithic applications, we normally use distributed transactions(XA) and two-phase commit(2PC) to maintain data consistency and integrity.

After moving to microservices architecture, we don’t have the option to use XA correctly technically; however, a lot of developer will use it implicitly without knowing the risk. In fact, they don’t even realize that they are using distributed transactions between microservices.

What is a distributed transaction

When we are talking about distributed transactions in the monolithic world, we are talking about explicit distributed transactions. In microservices architecture people will not use explicit distributed transactions but they can use implicit distributed transactions if they are not very careful.

Graham Lea defines distributed transaction in his article - Distributed Transactions: The Icebergs of Microservices as:

Distributed transaction - any situation where a single event results in the mutation of two or more separate sources of data which cannot be committed atomically.

Risk of distributed transactions in microservices

A lot of developers use implicit distributed transactions between multiple microservices. It works most of the time, until one day, there is a small network glitch and the data of your application is messed up as the application designer only thinks about happy paths.

This happens when one command from the UI triggers two or more microservices to update their states. If everything is perfect, all updates will be successful and everybody is happy. But what if the first service update succeeds and the second fails due to a network issue? Is this acceptable in your business? The majority of business people will answer no.

Given the fact that we are doing microservices, how do we resolve the data consistency issue between services.? There are solutions based on how these services interact with each other.

Solution - request/response

When service to service communication is synchronous, the options are very limited. Graham Lea documented some solutions in his article and I have written some related articles before.

  • Idempotency of Microservices
  • How to handler partial failure

Solution - event based

A microservices architecture promotes availability over consistency, hence leveraging a distributed transaction coordinator with a two-phase commit protocol is usually not an option. It gets even more complicated with the idea that these loosely-coupled data repositories might not necessarily all be relational stores and could be a polyglot with a mix of relational and non-relational data stores. The idea of having an immediately consistent state is difficult. What you should look forward to, however, is an architecture that promotes eventual consistency like CQRS and Event Sourcing. An event driven architecture can support a BASE (basic availability, soft-state, and eventual consistency) transaction model. This is a great technique to solve the problem of handling transactions across services and customers can be convinced to negotiate the contract towards a BASE model since usually transactional consistency across functional boundaries is mostly about frequent change of states, and consistency rules can be relaxed to let the final state be eventually visible to the consumers.

To enable developers to use an event driven approach for service to service communication, we have provided light-eventuate-4j which supports Event Sourcing and CQRS with Kafka as event broker. You can build your service with light-rest-4j, light-graphql-4j or light-hybrid-4j. They will communicate with each other asynchronously with events and eventually the states of each service will be consistent.

XA in one service

We’ve talked above about transactions across multiple microservices. How about XA transactions in one service? For example, in one service, it updates two different databases in one transaction or updates one database and pushes a message into the MQ queue in the same transaction.

In general, it is OK to use XA in one service and for light-*-4j frameworks, you can use a third party library to manage XA transactions even if we are not on the Java EE platform.

Transactions Essentials is an open source transaction manager and it is free.

Although it is doable with a Java SE JTA/XA transaction manager, it is not scaling at all. For high performance microservices, it would be better to adapt eventual consistency instead.

When discussing transactions between multiple microservices, light-eventuate-4j is recommended for resolving data consistency between services. In one service, it can still be used to eliminate the need for XA transactions.

Complex business transaction

For complex business transactions, achieving only eventual consistency is not enough. Saga pattern should be used to ensure that a partial of services can be rolled back with compensation steps if one of the services fails.

Our saga implementation is still a work in progress. Here is an article explaining it well.

See Also

  • Fail Fast vs Fail Slow
  • Eco System
  • CQRS
  • Event Sourcing
  • Service Mesh
  • About Light
    • Overview
    • Testimonials
    • What is Light
    • Features
    • Principles
    • Benefits
    • Roadmap
    • Community
    • Articles
    • Videos
    • License
    • Why Light Platform
  • Getting Started
    • Get Started Overview
    • Environment
    • Light Codegen Tool
    • Light Rest 4j
    • Light Tram 4j
    • Light Graphql 4j
    • Light Hybrid 4j
    • Light Eventuate 4j
    • Light Oauth2
    • Light Portal Service
    • Light Proxy Server
    • Light Router Server
    • Light Config Server
    • Light Saga 4j
    • Light Session 4j
    • Webserver
    • Websocket
    • Spring Boot Servlet
  • Architecture
    • Architecture Overview
    • API Category
    • API Gateway
    • Architecture Patterns
    • CQRS
    • Eco System
    • Event Sourcing
    • Fail Fast vs Fail Slow
    • Integration Patterns
    • JavaEE declining
    • Key Distribution
    • Microservices Architecture
    • Microservices Monitoring
    • Microservices Security
    • Microservices Traceability
    • Modular Monolith
    • Platform Ecosystem
    • Plugin Architecture
    • Scalability and Performance
    • Serverless
    • Service Collaboration
    • Service Mesh
    • SOA
    • Spring is bloated
    • Stages of API Adoption
    • Transaction Management
    • Microservices Cross-cutting Concerns Options
    • Service Mesh Plus
    • Service Discovery
  • Design
    • Design Overview
    • Design First vs Code First
    • Desgin Pattern
    • Service Evolution
    • Consumer Contract and Consumer Driven Contract
    • Handling Partial Failure
    • Idempotency
    • Server Life Cycle
    • Environment Segregation
    • Database
    • Decomposition Patterns
    • Http2
    • Test Driven
    • Multi-Tenancy
    • Why check token expiration
    • WebServices to Microservices
  • Cross-Cutting Concerns
    • Concerns Overview
  • API Styles
    • Light-4j for absolute performance
    • Style Overview
    • Distributed session on IMDG
    • Hybrid Serverless Modularized Monolithic
    • Kafka - Event Sourcing and CQRS
    • REST - Representational state transfer
    • Web Server with Light
    • Websocket with Light
    • Spring Boot Integration
    • Single Page Application
    • GraphQL - A query language for your API
    • Light IBM MQ
    • Light AWS Lambda
    • Chaos Monkey
  • Infrastructure Services
    • Service Overview
    • Light Proxy
    • Light Mesh
    • Light Router
    • Light Portal
    • Messaging Infrastructure
    • Centralized Logging
    • COVID-19
    • Light OAuth2
    • Metrics and Alerts
    • Config Server
    • Tokenization
    • Light Controller
  • Tool Chain
    • Tool Chain Overview
  • Utility Library
  • Service Consumer
    • Service Consumer
  • Development
    • Development Overview
  • Deployment
    • Deployment Overview
    • Frontend Backend
    • Linux Service
    • Windows Service
    • Install Eventuate on Windows
    • Secure API
    • Client vs light-router
    • Memory Limit
    • Deploy to Kubernetes
  • Benchmark
    • Benchmark Overview
  • Tutorial
    • Tutorial Overview
  • Troubleshooting
    • Troubleshoot
  • FAQ
    • FAQ Overview
  • Milestones
  • Contribute
    • Contribute to Light
    • Development
    • Documentation
    • Example
    • Tutorial
“Transaction Management” was last updated: April 5, 2021: Issue246 (#256) (50b1c10)
Improve this page
  • News
  • Docs
  • Community
  • Reddit
  • GitHub
  • About Light
  • Getting Started
  • Architecture
  • Design
  • Cross-Cutting Concerns
  • API Styles
  • Infrastructure Services
  • Tool Chain
  • Utility Library
  • Service Consumer
  • Development
  • Deployment
  • Benchmark
  • Tutorial
  • Troubleshooting
  • FAQ
  • Milestones
  • Contribute