Java Backend Architecture: Distributed Locks, Sessions & Maven Tips

This article covers Java backend architecture fundamentals, including front‑end/back‑end separation, Maven configuration, distributed lock implementations with Redis and Zookeeper, session handling in distributed systems, database locking strategies, and useful code snippets for common patterns.

Java High-Performance Architecture
Java High-Performance Architecture
Java High-Performance Architecture
Java Backend Architecture: Distributed Locks, Sessions & Maven Tips

Architecture

Discusses front‑end/back‑end separation and the relationship between Nginx and Tomcat. Provides a brief overview of Maven's settings.xml (global configuration) versus pom.xml (project‑level configuration) and how Maven stores dependencies in a local repository.

Distributed Locks

Explains three lock types: thread lock (effective only within a single JVM), process lock (across processes on the same OS), and distributed lock (across multiple machines). Lists three common implementations: database optimistic lock, Redis‑based lock, and Zookeeper‑based lock.

Redis‑Based Distributed Lock

Key Redis commands:

SETNX – set value only if key does not exist.

GETSET – get old value while setting a new one.

EXPIRE – set key expiration time.

Typical lock acquisition pattern using Jedis:

jedis.set(String key, String value, String nxxx, String expx, int time)

Incorrect patterns:

Long result = jedis.setnx(key, value);
if (result == 1) {
    // crash here → no expiration → deadlock
    jedis.expire(key, expireTime);
}

Another flawed approach that assumes synchronized clocks across clients:

long expires = System.currentTimeMillis() + expireTime;
String expiresStr = String.valueOf(expires);
if (jedis.setnx(lockKey, expiresStr) == 1) {
    return true;
}
String currentValueStr = jedis.get(lockKey);
if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
    String oldValueStr = jedis.getSet(lockKey, expiresStr);
    if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
        return true;
    }
}
return false;

Unlocking is performed by verifying ownership and calling jedis.del(lockKey).

Zookeeper‑Based Distributed Lock

Zookeeper provides a hierarchical namespace of znodes. Clients create a temporary sequential node under a designated locker node. The client that holds the smallest sequence number acquires the lock. If not the smallest, the client watches the next smaller node and retries when that node is deleted.

Create a temporary sequential node under /locker.

List all children of /locker (no watcher needed).

If the created node has the smallest sequence number, the lock is obtained.

Otherwise, watch the immediate predecessor node.

When the predecessor node is deleted, re‑evaluate to see if the current node is now the smallest.

Session in Distributed Systems

Describes the difference between traditional HTTP session (stored in a cookie) and token‑based authentication (token placed in request headers). Highlights the problem of session loss when load balancers route successive requests of the same user to different servers.

Common solutions include storing session data in Redis, using IP‑hash routing, or vertical scaling to keep a user’s requests on the same server.

Redis as a Distributed Lock

Mentions high concurrency design, Java synchronization concepts (wait/notify, synchronized, ReentrantLock), and thread states (BLOCK, WAIT, RUNNABLE). Provides brief Q&A about why wait / notify must be used inside a synchronized block.

Database Locks

Shows an example of a pessimistic lock using SQL:

SELECT * FROM account WHERE name = "Erica" FOR UPDATE

And a Hibernate code‑level lock:

String hql = "from TUser as user where user.name='Erica'";
Query query = session.createQuery(hql);
query.setLockMode("user", LockMode.UPGRADE);
List userList = query.list();

Other Topics

Brief notes on Lombok @Data, Java 8 Stream API, the enhanced for‑each loop, Spring validation with @Valid and BindingResult, converting a List to a Map using streams, and differences between List and Set. Also covers HashMap internals, load factor (default 0.75), and the transition from linked list to red‑black tree when a bucket exceeds eight entries.

Architecture diagram
Architecture diagram
Architecture diagram
Architecture diagram
Architecture diagram
Architecture diagram
JavaRedismavenDistributed LockSession
Java High-Performance Architecture
Written by

Java High-Performance Architecture

Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.

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.