fix:添加分布式锁,并用paifox测试

上级 40b20e87
package com.kwan.springbootkwan.annotation;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface RedisLock {
String value() default "";
@AliasFor("key")
String name() default "";
@AliasFor("name")
String key() default "";
long expire() default 30000; // 默认锁的过期时间,单位毫秒
long timeout() default 0; // 默认获取锁的超时时间,单位毫秒
boolean fair() default false; // 是否使用公平锁
}
package com.kwan.springbootkwan.aop;
import com.kwan.springbootkwan.annotation.RedisLock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Aspect
@Component
@Order(1) // 设置切面优先级
public class RedisLockAspect {
private final StringRedisTemplate redisTemplate;
public RedisLockAspect(StringRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Around("@annotation(redisLock)")
public Object doWithLock(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {
String lockKey = getLockKey(redisLock);
Lock lock = new ReentrantLock(redisLock.fair());
boolean locked = false;
try {
locked = lock.tryLock(redisLock.timeout(), TimeUnit.MILLISECONDS);
if (locked) {
if (StringUtils.hasText(lockKey)) {
redisTemplate.opsForValue().set(lockKey, "locked", redisLock.expire(), TimeUnit.MILLISECONDS);
}
return joinPoint.proceed();
} else {
throw new RuntimeException("Failed to acquire lock.");
}
} finally {
if (locked) {
lock.unlock();
if (StringUtils.hasText(lockKey)) {
redisTemplate.delete(lockKey);
}
}
}
}
private String getLockKey(RedisLock redisLock) {
String lockKey = redisLock.key();
if (!StringUtils.hasText(lockKey)) {
lockKey = redisLock.name();
}
return lockKey;
}
}
...@@ -8,7 +8,6 @@ import com.kwan.springbootkwan.entity.Result; ...@@ -8,7 +8,6 @@ import com.kwan.springbootkwan.entity.Result;
import com.kwan.springbootkwan.entity.dto.ChatbotDTO; import com.kwan.springbootkwan.entity.dto.ChatbotDTO;
import com.kwan.springbootkwan.service.ChatbotService; import com.kwan.springbootkwan.service.ChatbotService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
...@@ -57,11 +56,11 @@ public class ChatbotController { ...@@ -57,11 +56,11 @@ public class ChatbotController {
/** /**
* 分页查询所有数据 * 分页查询所有数据,本地缓存的使用
* *
* @return 所有数据 * @return 所有数据
*/ */
@Cacheable("chatbot-cache") // @Cacheable("chatbot-cache")
@GetMapping("/page") @GetMapping("/page")
public Result selectAll(@RequestParam Integer page public Result selectAll(@RequestParam Integer page
, @RequestParam Integer pageSize , @RequestParam Integer pageSize
......
package com.kwan.springbootkwan.controller; package com.kwan.springbootkwan.controller;
import com.kwan.springbootkwan.annotation.RedisLock;
import com.kwan.springbootkwan.entity.Department; import com.kwan.springbootkwan.entity.Department;
import com.kwan.springbootkwan.service.DepartmentService; import com.kwan.springbootkwan.service.DepartmentService;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
...@@ -63,6 +70,8 @@ public class DepartmentController { ...@@ -63,6 +70,8 @@ public class DepartmentController {
@GetMapping("/all") @GetMapping("/all")
@RedisLock(key = "myLock_queryTreeAll", expire = 5000, timeout = 3000)
// @RedisLock(key = "myLock_queryTreeAll", timeout = 10000)
public ResponseEntity<List<Department>> queryTreeAll() { public ResponseEntity<List<Department>> queryTreeAll() {
return ResponseEntity.ok(this.departmentService.queryTreeAll()); return ResponseEntity.ok(this.departmentService.queryTreeAll());
} }
......
...@@ -18,7 +18,6 @@ public class TimeFilter implements Filter { ...@@ -18,7 +18,6 @@ public class TimeFilter implements Filter {
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// log.info("先执行:接口执行时间");
chain.doFilter(request, response); chain.doFilter(request, response);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册