Introduction
In a distributed system, maintaining data integrity and consistency is very challenging. To implement Hazelcast transaction Management, Hazelcast provides features that make it easy to manage transactions and data consistency. Hazelcast is a high-performance, in-memory data grid(IMDG) which supports distributed caching, computation, and messaging.
In this article, we will explore the features of Hazelcast Transaction Management in practical examples.
Understanding Transaction Management in Distributed Systems
Hazelcast transaction management is a mechanism that provides you with a feature to perform atomic operations in a distributed environment. It ensures multiple operations can execute in a single transaction boundary, in case of failure the whole transaction gets rollback. By using this it maintains the data consistency and integrity.
Hazelcast uses a two-phase commit protocol, it ensures and guarantees that all the nodes that participated in the transaction will get rollback or commit.
Hazelcast Transaction Management Key Features ACID Properties:
- Atomicity: All the operations inside a transaction are atomic. In case of any failure on one operation then the entire transaction gets rolled back..
- Consistency: Stat of the data is consistent under the transaction.
- Isolation: Transactions are isolated, so the concurrent transactions interfere in the transactional process.
- Durability: After the successful transaction the data persisted in the storage.
Types of Transactions Supported by Hazelcast
Hazelcast transactions are used to ensure atomicity and consistency. Hazelcast provides two types of transaction:
1. Two-Phase Commit (2PC) Transaction
Two-phase commit transactions are very useful when working in distributed environments, where multiple operations are committed or rolled back.
How does 2PC transaction works?
- Begin Transaction: First transaction gets starts
- Perform Operations: Execute multiple operations as needed.
- Prepare Phase: In this step system checks, whether operations are successful or not.
- Commit/Rollback: If all the operations are successful then get commits, otherwise rollback.
Use Cases:
- Banking transactions where data consistency is important.
- Distributed databases where data get updated in multiple nodes.
2. One-Phase (Local) Transaction
One-Phase 1PC transactions are simple and fast, it is limited to a single node, and this transaction doesn’t have a prepare phase.
How does 1PC transaction works?
- Begin Transaction → Perform Operation → Commit/Rollback
- It is fast in execution because it executes in single node.
Use Cases:
- Low-latency applications where speed is important.
- In such a scenario where distributed consistency is not needed.
3. XA Transactions (Extended Architecture)
To implement Hazelcast transaction management, you can also be integrated with JTA (Java Transaction API) which supports XA transactions. These transactions are used to handle multiple transactional systems.
Use Cases:
- Microservices architectures where multiple databases interact.
- Enterprise-level applications where distributed transactions are important.
Implementing Transactions in Hazelcast
To implement Hazelcast transaction management, you can use TransactionContext
and TransactionMap
components. We will explore a step-by-step guide using Hazelcast transactions.
Pre-requisite:
- Java 8 or higher version
- Maven or Gradle
- Understanding about Hazelcast Maps
Hazelcast dependencies:
if you are using Maven:
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>5.5.0</version> <!-- Use the latest stable version -->
</dependency>
If you’re using Gradle, add below:
implementation 'com.hazelcast:hazelcast:5.5.0'
Step 1: Start Hazelcast Instance
First, we need to start the Hazelcast instance:
// Step 1: Create Hazelcast instance
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
Step 2: Configure Transaction Options (TWO_PHASE
or ONE_PHASE
)
Configure the TransactionOptions
with TransactionType.TWO_PHASE
.
// Step 2: Configure transaction options (TWO_PHASE or ONE_PHASE)
TransactionOptions options = new TransactionOptions()
.setTransactionType(TransactionOptions.TransactionType.TWO_PHASE);
Step 3: Start a Hazelcast Transaction
Initialize Hazelcast TransactionContext
by using transaction options and begin the transaction.
// Step 3: Start a transaction
TransactionContext transactionContext = hazelcastInstance.newTransactionContext(options);
transactionContext.beginTransaction();
Step 4: Perform Transaction Operation
Create a Hazelcast Transactional
Map
and Queue
object by using transactionContext
,
// Step 4: Perform operations inside the transaction
TransactionalMap<String, String> transactionalMap = transactionContext.getMap("JavaTechARC_Map");
TransactionalQueue<String> transactionalQueue = transactionContext.getQueue("JavaTechARC_Queue");
transactionalMap.put("1", "Java Tech ARC 3i Hazelcast Transaction Map Test");
transactionalQueue.offer("ava Tech ARC 3i Transaction Queue Test");
// Simulate a condition to rollback, with condition true
if (false) { // Change to false to see successful commit
throw new RuntimeException("Simulated Error: Rolling back transaction!");
}
- In this example putting one single string object into Map with Map
put
operation. - Also, add one single string object to the queue with the queue offer.
- To simulate exceptions, you can use TRUE or FALSE to generate commit or rollback conditions.
Step 5: Commit the Transaction
Commit the transaction associated with transactionContext
, if everything fine in operations
// Step 5: Commit transaction if everything is fine
transactionContext.commitTransaction();
System.out.println("Transaction committed successfully!");
Step 6: Rollback the Transaction
In case of any exception that occurs during the operation processing, then call the rollbackTransaction()
. It will roll back everything associated with transactionContext
.
// Step 6: Rollback in case of failure
transactionContext.rollbackTransaction();
System.out.println("Transaction rolled back due to error: " + e.getMessage());
Complete Sample Code
Complete sample code explained on above example:
package com.javatecharc.demo.hazelcast.transaction;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.transaction.TransactionContext;
import com.hazelcast.transaction.TransactionOptions;
import com.hazelcast.transaction.TransactionalMap;
import com.hazelcast.transaction.TransactionalQueue;
public class HazelcastTransactionExample {
public static void main(String[] args) {
// Step 1: Create Hazelcast instance
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
// Step 2: Configure transaction options (TWO_PHASE or ONE_PHASE)
TransactionOptions options = new TransactionOptions()
.setTransactionType(TransactionOptions.TransactionType.TWO_PHASE);
// Step 3: Start a transaction
TransactionContext transactionContext = hazelcastInstance.newTransactionContext(options);
transactionContext.beginTransaction();
try {
// Step 4: Perform operations inside the transaction
TransactionalMap<String, String> transactionalMap = transactionContext.getMap("JavaTechARC_Map");
TransactionalQueue<String> transactionalQueue = transactionContext.getQueue("JavaTechARC_Queue");
transactionalMap.put("1", "Java Tech ARC 3i Hazelcast Transaction Map Test");
transactionalQueue.offer("ava Tech ARC 3i Transaction Queue Test");
// Simulate a condition to rollback, with condition true
if (false) { // Change to false to see successful commit
throw new RuntimeException("Simulated Error: Rolling back transaction!");
}
// Step 5: Commit transaction if everything is fine
transactionContext.commitTransaction();
System.out.println("Transaction committed successfully!");
} catch (Exception e) {
// Step 6: Rollback in case of failure
transactionContext.rollbackTransaction();
System.out.println("Transaction rolled back due to error: " + e.getMessage());
} finally {
// Shutdown Hazelcast instance
hazelcastInstance.shutdown();
}
}
}
Hazelcast Transaction Management Best Practices
You can follow some best practices, and implement Hazelcast transaction management.
- Short Transactions: Transaction operation processing should be short, to avoid performance impact.
- Error Handling: Always use try-catch blocks to handle exceptions and rollback.
- Isolation Levels: Hazelcast provides default isolation level
REPEATABLE_READ
. You can configure another isolation level if required. - Concurrency Control: High concurrency scenarios, use the distributed lock to maintain consistency.
Hazelcast Transactions vs. Traditional Databases
Pros and Cons of Hazelcast Transactions
✅ Pros
- Process high-speed in-memory data
- Horizontally scalable for distributed systems
- Supported architectures microservices and cloud natives
❌ Cons
- Processing large datasets requires more system memory.
- Strict ACID compliance in not always suitable
- Differ transaction visibility for different traditional RDBMS databases.
Conclusion
Implement Hazelcast Transaction Management to maintain consistency and integrity in distributed systems. By using this you can perform atomic operations, it ensures that in case of failure, all the operation gets rolled back. In the above-given example, we have explained how to implement Hazelcast Transaction Management in a distributed environment. You can use the best practices of Hazelcast transaction management to build high-performance and reliable applications.
The sample code is available on GitHub.
Also, explore the below articles:
- How to Start Hazelcast Members and Client?
- Hazelcast SQL Queries: A Complete Example for Developers
- Hazelcast Paging Predicate with JSON Data: A Complete Guide
- Understanding of Hazelcast QueueStore
- Understanding of Hazelcast MapLoader
- Understanding of Hazelcast MapStore
FAQs
- What are the main benefits of Hazelcast transactions?
- Can Hazelcast transactions work with NoSQL databases?
- How does Hazelcast compare to Kafka transactions?
- What is the best way to monitor Hazelcast transactions?
- Are Hazelcast transactions suitable for real-time applications?