Many people like redisson
to encapsulate the continuation as a comment, not to say good or bad, just want to say that the smaller the lock granularity, the better.
Introducing the package into the project
Version use3.11.1
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
Configuration file addition
spring.redis.cluster.nodes = xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx
spring.redis.password = passwd
Example①
@Autowired
private RedissonClient redissonClient;
public void lockTest(){
RLock lock = redissonClient.getLock(RedisConst.LOCK_PREFIX+"lock:order:xxxxxx");
try {
// 这里要根据实际业务使用isLocked()
if (lock.tryLock(5,30, TimeUnit.SECONDS)) {
//todo 这里实现你的业务逻辑,锁使用原则,粒度越小越好
}
} catch (InterruptedException e) {
System.out.println("获取锁异常");
}finally {
lock.unlock();
}
}
Example ② Optimistic lock scenario
RLock lock = redissonClient.getLock(RedisConst.LOCK_PREFIX + "COMMIT_LOCK");
boolean res=false;
try {
res = lock.tryLock(0, 10, TimeUnit.SECONDS);
System.out.println(res);
if (res){
System.out.println("获取到锁了");
}
if (!res) {
return BusinessResultModel.fail("操作太频繁!");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
Trylock parameter description
-
-- waitTime
: The longest waiting time for the first parameter to get the lock. If the lock is retrieved within this timetrue
, it will return , if the lock is not retrieved after this time, it will returnfalse
-
-- leastTime
: The second parameter is the lock expiration time after the lock is obtained. The lock will be released when the service has not been executed after this time. -
-- TimeUnit
: The third parameter, time unit.
Due to the complexity of the code business, there will be the following situations:
- 1. In the case of three threads concurrently, we assume that the thread
A、B、C
Thread A acquires the lock, and the B
thread cannot get the lock when it comes in. At this time, the B
thread executes the finally
method A
and releases the lock. At this time, the thread gets the lock and gets the lock. C
Then the AC
thread executes the same piece of code at the same time.
Solution: In fact, this problem does not exist, because the redisson
lock can only be released by the thread that currently acquires the lock, so the call lock.unlock()
does not need to be judged.
- 2.
AB
Two threads are executed in non-concurrent execution. Suppose that after the execution of thread A completes and returns, theB
thread comes in and executes the same piece of code. In fact, theAB
two threads have the same request content. This is actually an idempotent problem.
At this time, dirty data will appear in the database due to business problems. For example, if a payment order is generated based on the same order number, two id
different payment orders will be generated .
Solution: To judge the same request through the business, take the above example as an example: the condition is the same order number, to judge whether the order has been processed, if it has been processed, it will directly return to the processing success. Or return to processed.
- 3. According to
trylock
the parameters, we can know that if I want to get the lock retrieval result immediately, just set the first parameter0
to