Master Distributed Sessions, Transactions, and Locks in Java – Practical Guides & Code

This article explains how to implement distributed session management, transaction handling, and locking mechanisms in Java applications, covering Tomcat‑Redis integration, Spring Session with Redis, various distributed transaction patterns, and both Redis and Zookeeper based distributed locks with complete code examples.

Programmer DD
Programmer DD
Programmer DD
Master Distributed Sessions, Transactions, and Locks in Java – Practical Guides & Code

1. Distributed Session

In a single‑node system, the browser sends a jsessionid cookie which the server uses to locate a session object where data can be stored. When scaling to multiple servers, the session state must be shared.

Approach 1: No session – Use JWT tokens for identity and fetch other data from a database or cache.

Approach 2: Tomcat + Redis – Keep the same session code but store session data in Redis using TomcatRedisSessionManager:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="{redis.host}"
         port="{redis.port}"
         database="{redis.dbnum}"
         maxInactiveInterval="60"/>

For high availability you can use Redis Sentinel configuration:

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         sentinelMaster="mymaster"
         sentinels="<sentinel1-ip>:26379,<sentinel2-ip>:26379,<sentinel3-ip>:26379"
         maxInactiveInterval="60"/>

Approach 3: Spring Session + Redis – Add dependencies:

<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>1.2.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.1</version>
</dependency>

Spring configuration:

<bean id="redisHttpSessionConfiguration"
      class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    <property name="maxInactiveIntervalInSeconds" value="600"/>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="100"/>
    <property name="maxIdle" value="10"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    <property name="hostName" value="${redis_hostname}"/>
    <property name="port" value="${redis_port}"/>
    <property name="password" value="${redis_pwd}"/>
    <property name="timeout" value="3000"/>
    <property name="usePool" value="true"/>
    <property name="poolConfig" ref="jedisPoolConfig"/>
</bean>

web.xml filter registration:

<filter>
  <filter-name>springSessionRepositoryFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>springSessionRepositoryFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Example controller using the native session API (now backed by Redis):

@RestController
@RequestMapping("/test")
public class TestController {

    @RequestMapping("/putIntoSession")
    public String putIntoSession(HttpServletRequest request, String username) {
        request.getSession().setAttribute("name", "leo");
        return "ok";
    }

    @RequestMapping("/getFromSession")
    public String getFromSession(HttpServletRequest request, Model model) {
        String name = (String) request.getSession().getAttribute("name");
        return name;
    }
}

These three methods cover the most common ways to achieve distributed session storage in Java.

2. Distributed Transaction

When a single database becomes a bottleneck, data is sharded across multiple physical nodes, breaking the classic ACID guarantees. The CAP theorem (Consistency, Availability, Partition tolerance) explains why a distributed system cannot simultaneously provide all three properties.

Common distributed transaction solutions (five major patterns):

XA (two‑phase commit)

TCC (Try‑Confirm‑Cancel)

Local message table

Reliable message with eventual consistency

Maximum effort notification

XA (Two‑Phase Commit)

A transaction manager coordinates multiple resource managers. In the first phase each DB prepares; if all reply OK, the second phase commits, otherwise all roll back. Typically used with Spring + JTA, but not recommended for high‑concurrency micro‑service scenarios.

TCC

Three stages:

Try – reserve resources and lock them.

Confirm – execute the actual business logic.

Cancel – if any step fails, run compensating actions to roll back.

Often applied to financial operations where strong consistency is required.

Local Message Table

Each service writes a message to its own DB table and then publishes it to a message queue. The consumer service processes the message in its own transaction and updates both tables. This guarantees eventual consistency but can be hard to scale under high load.

Reliable Message (e.g., RocketMQ Transactional Message)

Producer sends a prepared message, executes a local transaction, then confirms or rolls back the message based on the transaction outcome. The broker periodically checks the transaction status to handle network failures.

Maximum Effort Notification

After a local transaction, a message is sent to a dedicated consumer that records the event and retries calling the downstream service until success or a retry limit is reached.

3. Distributed Lock

Redis Simple Lock

Acquire lock: SET my:lock <randomValue> NX PX 30000 Release lock safely with a Lua script that deletes the key only if the stored value matches:

if redis.call("get", KEYS[1]) == ARGV[1] then
  return redis.call("del", KEYS[1])
else
  return 0
end

Limitations: single‑node Redis is a single point of failure; master‑slave replication may lose the lock if the master crashes before replication.

RedLock Algorithm (Redis Cluster)

Assume five Redis masters. The client:

Gets the current timestamp.

Attempts to set the lock on each master with a short TTL.

Requires a majority (N/2+1) of masters to succeed.

If the total time to acquire the lock is less than the TTL, the lock is considered acquired.

If acquisition fails, the client releases any partial locks.

Zookeeper Distributed Lock

Create an EPHEMERAL node; the first client that creates it obtains the lock. Others watch the node and wait for its deletion.

public class ZooKeeperSession {
    private static CountDownLatch connectedSemaphore = new CountDownLatch(1);
    private ZooKeeper zk;
    public ZooKeeperSession() throws Exception {
        zk = new ZooKeeper("host1:2181,host2:2181,host3:2181", 50000, event -> {
            if (event.getState() == KeeperState.SyncConnected) {
                connectedSemaphore.countDown();
            }
        });
        connectedSemaphore.await();
    }
    public boolean acquireDistributedLock(Long productId) throws Exception {
        String path = "/product-lock-" + productId;
        try {
            zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            return true;
        } catch (NodeExistsException e) {
            // watch the existing node
            zk.exists(path, true);
            return false;
        }
    }
    public void releaseDistributedLock(Long productId) throws Exception {
        String path = "/product-lock-" + productId;
        zk.delete(path, -1);
    }
}

Advantages over Redis lock: Zookeeper automatically removes the EPHEMERAL node if the client crashes, eliminating stale locks; also uses watches instead of busy‑waiting.

Overall, the article provides practical code and configuration examples for implementing distributed session storage, transaction coordination, and locking in Java‑based backend systems.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

redisZooKeeperdistributed-transactionDistributed Session
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.