您可以在 Shedlock 的文档中找到,为了延长最大锁定时间lockAtMostUntil
,您必须手动创建SimpleLock
和方法。extend()
请记住,您还必须extend()
手动调用该方法,或者通过实现一个check()
方法来检查您的进程是否完成并在需要时调用该方法,否则,无论您的进程是否extend()
到达时间,锁都会自动解锁lockAtMostUntil
仍在运行。
在这里,我将解释如何SimpleLock
手动从LockProvider
. 关于如何设置数据库的问题,我建议您阅读 Shedlock 的这部分文档。
我已经用于spring boot
我的应用程序,所以您看到的注释来自spring boot
.
依赖项:
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.23.0</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>4.23.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
配置LockProvider
:_
@EnableAsync
@Profile("!unit_test")
@Configuration
public class LockConfiguration {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withTimeZone(TimeZone.getTimeZone("Europe/Rome"))
.withJdbcTemplate(new JdbcTemplate(dataSource))
.withTableName("shared_lock")
.usingDbTime()
.build());
}
}
这里的DistributedLockSimpleLock
是我们实现和所有需要的相关方法的地方:
@Component
@Slf4j
public class DistributedLockWithExtend {
@Autowired
private LockProvider lockProvider;
private final Map<String, SimpleLock> locks = new HashMap<>();
public boolean tryLock(String lockname, Duration lockDuration){
Duration minDuration = Duration.ZERO;
Instant now = ClockProvider.now();
LockConfiguration config = new LockConfiguration(now, lockname, lockDuration, minDuration);
Optional<SimpleLock> lockLocal = lockProvider.lock(config);
if(lockLocal.isPresent()) {
locks.put(lockname, lockLocal.get());
log.debug("lock is created!");
return true;
}else {
log.debug("lock is locked!");
return false;
}
}
public boolean extendLock(String lockname, Duration duration){
Duration minDuration = Duration.ZERO;
SimpleLock lock = locks.get(lockname);
if(lock != null) {
Optional<SimpleLock> localLock = lock.extend(duration, duration);
locks.put(lockname, localLock.get());
log.debug("Lock is extended");
return true;
}else {
log.debug("There is no lock or the lock is already unlocked! Create a lock with tryLock() if you need!");
return false;
}
}
public String unLock(String lockname){
SimpleLock lock = locks.get(lockname);
if(lock != null) {
locks.remove(lockname);
lock.unlock();
log.debug("Lock is unLocked!");
return "Lock is unLocked!";
}else {
log.debug("There is no lock or the lock is already unlocked! Create a lock if you need!");
return "There is no lock or the lock is already unlocked! Create a lock if you need!";
}
}
}
这是我创建的一个测试RestController来演示这些DistributedLockWithExtend
方法的用法:
@Profile("!unit_test")
@RestController
@RequestMapping(TestLockController.PATH)
public class TestLockController {
public static final String PATH = BaseController.PATH + "/test-lock";
@Autowired
ApplyPolicyScheduler applyPolicySchedular;
@Autowired
DistributedLockWithExtend distributedLockWithExtend;
@GetMapping("/up")
public String testService(){
return "Service is up!";
}
@GetMapping("/invoke")
public String invokeTest(){
return distributedLockWithExtend.tryLock("testLockUtil", Duration.ofMinutes(1)) + "";
}
@GetMapping("/extend")
public String extendTest(){
return distributedLockWithExtend.extendLock("testLockUtil", Duration.ofMinutes(3)) + "";
}
@GetMapping("/unlock")
public String unlockTest(){
distributedLockWithExtend.unLock("testLockUtil");
return "Unlock called!";
}
}