type
status
date
slug
summary
tags
category
icon
password
📌
This is one excerpt from the main website(CN) blog, check link below to know more.

Distributed Lock,Customized AOP,Redisson,SPEL

Distributed Lock

  • Background: The “Synchronized” lock in Java is implemented based on the JVM Monitor. In a clustered environment, multiple JVMs mean multiple monitors, which cannot achieve mutual exclusion. Therefore, there should be one single lock across multiple instances, which is called distributed lock.
  • It seems a Distributed Lock can be implemented with Redis?
      1. Redis can be accessed by multiple JVM instances.
      1. The SETNX command provides mutual exclusion.
      1. The DEL command can be used to release the lock.
      1. Redis executes commands in a single-threaded (serial) manner.
  • Potential Issues:
    • Direct Implementation:
      • SET lock thread1 NX EX 20 – This involves two main steps.
    • 1. Timeout Release:
      • The lock may not be properly released (for example, if redis instance crashes), which could lead to a deadlock. Setting an expiration time is necessary to mitigate this (in the example, the lock acquisition and expiration time setting are performed atomically).
    • 2. Storing thread Identifier:
      • The lock stores the identifier of the thread that acquired it, and it should only be deleted if the identifier matches. This helps prevent accidental release of the lock (however, it cannot be completely avoided).
        Image source(CN website): https://b11et3un53m.feishu.cn/wiki/wikcnkbaeh4T9AyYlM7rHSaKMsc
        notion image
        (IMG:thread 1 got blocked before its release of lock, the lock got itself released due to timeout which allowed thread 2 to get its share, yet thread 1 then awake and ruin its day)
        notion image
        (IMG:now thread 1 can no longer release the lock after timeout since the identifier is thread 2, not thread 1, and thread 1 cannot release the lock for the identifier does not correspond)
         
        However, since the check and deletion are not atomic, there is still a risk of accidental deletion.
        notion image
        (IMG:thread 1 may check the identifier before its release move, and then directly release after its awakening from block, rendering the identifier mechanism ineffective)
       
      From above, we learn:
      Timeout-based release does not entirely prevent accidental deletion, and lock release operations require atomicity, there is also a problem on delays in master-slave synchronization, and the same thread may not be able to acquire the same lock multiple times (potentially leading to deadlocks), therefore such issues need to be addressed:
      • 1. Timeout Issue: Use a WatchDog mechanism. When a lock is successfully acquired, a scheduled task is started that automatically extends the lock’s expiration before it expires, thereby preventing a timeout release. This task also stops if the instance crashes, avoiding deadlocks.
      • 2. Atomicity Issue: Use Lua scripts to ensure atomic operations.
      • 3. Lock Reentrancy: Similar to the behavior of synchronized, a hash can be used to record the holder and the reentrancy count. The lock is deleted when the count drops to zero.
      • 4. Master-Slave Synchronization Delay: Use the RedLock.
      • 5. Lock Failure Retry: Implement mechanisms to retry obtaining the lock upon failure.
  • Mature Solution:
    • Redisson provides a well-tested, comprehensive implementation that addresses these issues.

Redisson Quick Start

maven import

Config class (with autoconfigure)

ConditionalOnClass autoconfigure - this config class only takes effect when you import Redisson dependency
Where does this RedisProperties come from?:
from the nacos config center
notion image
the config file (you may add these to the local config file in case you do not use config center)
notion image
resources/META-INF/spring.factories(for autoconfigure, mainly for conditional config class):

Basic usage of redisson client

Business Scenario
  • waitTime:how long you can wait, you can retry repeatedly before the time runs out. -1 by default,return immediately after failure, no retry.
  • leaseTime:how long you can use the lock before compulsory release。by default 30,keep renewing with WatchDog.
  • TimeUnit:in literal

Distributed Lock AOP (General Scenario)

  • avoid boilerplate code coupling with business logic
  • mark pointcut with annotation, passing params(lock name[SPEL expression, dynamic name], waitTime, leaseTime, timeunit) of lock meanwhile

Annotation

Aspect

Implement Ordered interface so you make sure the lock wraps @Transactional(any value less than Integer.MAX_VALUE should do), i.e higher precedence(lower value) in AOP.
This value of @Transactional is by default Integer.MAX_VALUE(fyr, org.springframework.transaction.annotation.EnableTransactionManagement)
notion image
btw, you may find something similar at:
org.springframework.context.annotation.ConfigurationClassUtils
except it’s for @Configuration
notion image

ENUM

Lock Type(Strategy Pattern)
Simple factory pattern(another way)
EnumMap implemented with pure array, likely faster than HashMap, fyr.
Implementation note: All basic operations execute in constant time. They are likely (though not guaranteed) to be faster than their HashMap counterparts.
Example in coupon discount strategy
Lock fail strategy
waitTime defines the time you may retry,no retry if no such param

Rewrite API with AOP

Results devoid of oversell(both for total and single user limit)
  • Find some lucky coupon
notion image
  • Fill its id in jmeter, configure threads and loop count (1k user, each try 3 times on the same coupon with 1 per user limit)
notion image
notion image
  • Done, check Redis 100 rows√ 1 per user√ 0 total left√
notion image
notion image
  • check DB 100 issue√
notion image
  • check summary report √
notion image
  • check jmeter report, should be only 100 true√
notion image
  • check reasons for failed http requests, 优惠卷库存不足(No enough inventory)√ 请求超时(Timeout for distributed lock retrying)√
notion image
notion image
notion image
  • Align with the failure strategy √
notion image
Full Code:
receive coupon
notion image
notion image
exchange coupon
notion image
 
Chrome extension recommendation中文主站访问右上角Main Site
Loading...
CamelliaV
CamelliaV
Java Dev; Medical CV; ACGN
Latest posts
Customized AOP for Distributed Lock
2025-3-21
中文主站访问右上角Main Site
2025-3-21
Chrome extension recommendation
2025-2-24
Download Youtube 4K Video
2025-2-24
Announcement
🧨Under Construction
 
2024-2025CamelliaV.

CamelliaV | Java Dev; Medical CV; ACGN