当配置多节点后端的时候,用@Scheduled会导致定时任务多次执行,会占用更多资源,严重的情况下会导致数据的错乱与缺失,加上原子锁可以避免发生这样的情况。
这边把redis原子锁的包加进来。
1 2 3 4 5 6
| <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.24.3</version> </dependency>
|
3.22.1把几个漏洞修补的最低版本,但要我目前使用Spring Boot Redis2.5,因此要做到适配的话,里面的包的版本得降下来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.22.1</version> <exclusions> <exclusion> <groupId>org.redisson</groupId> <artifactId>redisson-spring-data-31</artifactId> </exclusion> </exclusions> </dependency>
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-data-25</artifactId> <version>3.22.1</version> </dependency>
|
在业务代码中依赖注入相关的包。
1 2
| @Resource private RedissonClient redisson;
|
给业务代码加锁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Scheduled(cron = "0 0 0/1 * * ?") public void updateAuthorityForAllSelect(){ RLock lock = redisson.getLock("scheduled:bankend:data:update"); boolean locked = false; try { locked = lock.tryLock(3, 30, TimeUnit.SECONDS); if (!locked) { log.warn("未获取到锁,任务取消"); return; } userAuthorityMapper.userAuthorityMapper(); log.info("数据权限全量更新任务执行完成"); } catch (Exception e) { log.error("数据权限更新任务异常", e); throw new BaseException("指南针管理后台数据权限全权限更新任务异常"); } finally { if (locked && lock.isHeldByCurrentThread()) { lock.unlock(); } } }
|
注意在配置文件中配置的Redis,如果没有密码的话需要把password注释掉,否则会报错。