Spring Boot 锁定Reactive WebFlux?

5vf7fwbs  于 2023-05-22  发布在  Spring
关注(0)|答案(1)|浏览(189)
  • 因此,在获取特定线程上的锁后,我的代码进入临界区
  • 在我的关键部分,我使用了flatMap来改变线程
  • 现在,由于线程已更改,被释放的线程可能被分配给不同的任务
  • 现在,不同的任务可以进入我的临界区,即使我以前的任务还没有完成它的执行并释放锁

因此,我无法在React式Web通量项目中实现锁定

  • 因此,我制作了一个通用的锁定框架,它可以在项目中的任何地方使用(类似于注解)
  • 由于我应用注解的函数更改了线程,因此无法实现此逻辑

在这个问题上给出更多的背景-
NormalFlow.class

@ReactiveRedissonLock(<waitTime> <leaseTime> <lockingparams>)
Mono<String> testFunction() {
 return service.flatMap( value -> return dao.getValue() //now its waiting for dao to get the value
//thread1 is deallocated and might be allocated to a different process )
}

将以下代码视为LockAspect.class中的函数

public Object createLock(ProceedingJoinPoint joinPoint, ReactiveRedissonLock reactiveRedissonLock) throws Throwable {
        RLockReactive reactiveLock = getReactiveLock(requestParamMap, keyRoot);
        Long id = Thread.currentThread().getId(); // consider current thread to be thread1
//Lock taken on thread1, now thread1 can freely enter the critical section        
return 
reactiveLock.tryLock(reactiveRedissonLock.waitTime(), reactiveRedissonLock.leaseTime(), TimeUnit.SECONDS).flatMap(value -> {
            if (value == false) {
                return Mono.error(new AssessmentEngineException(HttpStatus.INTERNAL_SERVER_ERROR, "Multiple calls not allowed to this part of the code"));
            }
            try {
                return (Mono) joinPoint.proceed(); // call the normal flow of the function on which this annotation was applied
            } catch (Throwable e) {
                return Mono.error(new AssessmentEngineException(HttpStatus.INTERNAL_SERVER_ERROR, "Please check the return type used in redisson lock"));
            }
        }).doFinally(a -> reactiveLock.unlock(id).subscribe());
    }

现在我的问题是,由于thread 1被释放,并且可能被分配给不同的进程,即使前面的进程还没有完成它的执行,另一个进程也可以和thread 1一起进入这个临界区。
那么有没有一种方法可以在WebFlux中有效地实现锁定呢

ax6ht2ek

ax6ht2ek1#

我自己实现了不依赖于线程的锁,解决了这个问题。
基本上,我们在一个任务试图进入临界区(单原子事务,使用setIfAbsent)之前检查该键是否存在于redis中并设置它,如果它能够这样做,那么它将进入临界区,否则该任务将在超时之前等待。当该任务退出临界区时,它将从redis中删除该键,使其他等待进入临界区的任务再次进入临界区。

相关问题