mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
取消板件自动写入,bug1255,1225
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.cf.imes</groupId>
|
||||
<artifactId>cf-framework</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cf-spring-boot-starter-biz-id</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>主键id生成</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>provided</scope> <!-- 设置为 provided,只有工具类需要使用到 -->
|
||||
</dependency>
|
||||
|
||||
<!-- Test 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>com.cf.imes</groupId>
|
||||
<artifactId>cf-spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.cf.imes.framework.id.config;
|
||||
|
||||
import com.cf.imes.framework.id.core.util.SnowflakeIdWorker3rd;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* ip自动注册配置
|
||||
*
|
||||
* @author 晨丰科技
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class ChenfengIDAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public SnowflakeIdWorker3rd ipQueryService() {
|
||||
return new SnowflakeIdWorker3rd();
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.cf.imes.framework.id.core.util;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class MinuteCounter {
|
||||
private static final int MASK = 0x7FFFFFFF;
|
||||
private final AtomicInteger atom;
|
||||
|
||||
public MinuteCounter() {
|
||||
atom = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
public final int incrementAndGet() {
|
||||
return atom.incrementAndGet() & MASK;
|
||||
}
|
||||
|
||||
public int get() {
|
||||
return atom.get() & MASK;
|
||||
}
|
||||
|
||||
public void set(int newValue) {
|
||||
atom.set(newValue & MASK);
|
||||
}
|
||||
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
package com.cf.imes.framework.id.core.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @ClassName: SnowflakeIdWorker3rd
|
||||
* @Description:snowflake算法改进
|
||||
* @author: yonnie
|
||||
* @date: 2024/06/18 14:10:47
|
||||
* @version V1.0
|
||||
*
|
||||
* 将产生的Id类型更改为Integer 32bit <br>
|
||||
* 把时间戳的单位改为分钟,使用25bit的时间戳
|
||||
* 7bit作为自增值即 2^7 = 128
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class SnowflakeIdWorker3rd {
|
||||
/** 初始时间 (2024-01-01: 1704038400) */
|
||||
// private final int twepoch = 28400640;// 1704038400000L/1000/60;
|
||||
private final int twepoch = 1704038400;
|
||||
/** 序列在id中占位数 */
|
||||
private final long sequenceBits = 7L;
|
||||
/** 时间截向左移7bit */
|
||||
private final long timestampLeftShift = sequenceBits;
|
||||
/** 生成序列的MASK (0x7F) */
|
||||
private final int sequenceMask = -1 ^ (-1 << sequenceBits);
|
||||
/** 分钟内序 (0~127) */
|
||||
private int sequence = 0;
|
||||
private int laterSequence = 0;
|
||||
/** 上次生成ID的时间戳 */
|
||||
private int lastTimestamp = -1;
|
||||
private final MinuteCounter counter = new MinuteCounter();
|
||||
/** 预支时间标志 */
|
||||
boolean isAdvance = false;
|
||||
|
||||
// ==============================Constructors=====================================
|
||||
|
||||
public SnowflakeIdWorker3rd() {
|
||||
// No Args Constructors
|
||||
}
|
||||
|
||||
// ==============================Test=============================================
|
||||
|
||||
/** 测试 */
|
||||
public static void main(String[] args) {
|
||||
SnowflakeIdWorker3rd idWorker = new SnowflakeIdWorker3rd();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
long id = idWorker.nextId();
|
||||
System.out.println(i + ": " + id + " " + "2406" + Long.toString(id).substring(2));
|
||||
}
|
||||
// long id = idWorker.nextId();
|
||||
// System.out.println(id);
|
||||
}
|
||||
|
||||
// ==============================Methods==========================================
|
||||
/**
|
||||
* 获取当前年月
|
||||
* @return null
|
||||
*/
|
||||
public static int obtainingTime() {
|
||||
LocalDate now = LocalDate.now();
|
||||
int year = now.getYear();
|
||||
String year_last_two_digits = String.valueOf(year).substring(2);
|
||||
int month = now.getMonthValue();
|
||||
String formatted_date = year_last_two_digits + String.format("%02d", month);
|
||||
return Integer.parseInt(formatted_date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得下一个ID (该方法是线程安全)
|
||||
*
|
||||
* @return SnowflakeId
|
||||
*/
|
||||
public synchronized int nextId() {
|
||||
int timestamp = timeGen();
|
||||
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟修改过
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new RuntimeException(String.format(
|
||||
"Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
if (timestamp > counter.get()) {
|
||||
counter.set(timestamp);
|
||||
isAdvance = false;
|
||||
}
|
||||
|
||||
// 如果是同时间生成的,则进行分钟内序列
|
||||
if (lastTimestamp == timestamp || isAdvance) {
|
||||
if (!isAdvance) {
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
}
|
||||
|
||||
// 分钟内自增列溢出
|
||||
if (sequence == 0) {
|
||||
// 预支下一分获得新的时间戳
|
||||
isAdvance = true;
|
||||
int laterTimestamp = counter.get();
|
||||
if (laterSequence == 0) {
|
||||
laterTimestamp = counter.incrementAndGet();
|
||||
}
|
||||
int nextId = ((laterTimestamp - twepoch) << timestampLeftShift) | laterSequence;
|
||||
laterSequence = (laterSequence + 1) & sequenceMask;
|
||||
return nextId;
|
||||
}
|
||||
} else { // 时间戳改变,分钟内序列置0
|
||||
sequence = 0;
|
||||
laterSequence = 0;
|
||||
}
|
||||
// 上次生成ID的时间截
|
||||
lastTimestamp = timestamp;
|
||||
// 移位并或运算拼成32位的ID
|
||||
return ((timestamp - twepoch) << timestampLeftShift) | sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以分钟为单位的当前时
|
||||
*
|
||||
* @return 当前时间(分钟)
|
||||
*/
|
||||
protected int timeGen() {
|
||||
// String timestamp = String.valueOf(System.currentTimeMillis() / 1000 / 60);
|
||||
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
|
||||
return Integer.valueOf(timestamp);
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.cf.imes.framework.id.config.ChenfengIDAutoConfiguration
|
||||
+4
-1
@@ -4,6 +4,7 @@ import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||
import com.cf.imes.framework.common.util.json.JsonUtils;
|
||||
import com.cf.imes.framework.common.util.monitor.TracerUtils;
|
||||
@@ -310,7 +311,9 @@ public class OperateLogAspect {
|
||||
String argName = argNames[i];
|
||||
Object argValue = argValues[i];
|
||||
// 被忽略时,标记为 ignore 字符串,避免和 null 混在一起
|
||||
args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
|
||||
if (ObjectUtil.isNotNull(argValue)) {
|
||||
args.put(argName, !isIgnoreArgs(argValue) ? argValue : "[ignore]");
|
||||
}
|
||||
}
|
||||
return JsonUtils.toJsonString(args);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.amqp</groupId>
|
||||
<artifactId>spring-rabbit</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
|
||||
+85
-9
@@ -1,12 +1,25 @@
|
||||
package com.cf.imes.framework.mq.rabbitmq.config;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.utils.SerializationUtils;
|
||||
import org.springframework.amqp.core.Binding;
|
||||
import org.springframework.amqp.core.BindingBuilder;
|
||||
import org.springframework.amqp.core.DirectExchange;
|
||||
import org.springframework.amqp.core.FanoutExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.core.QueueBuilder;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_EXCHANGE;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_QUEUE;
|
||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY;
|
||||
|
||||
/**
|
||||
* RabbitMQ 消息队列配置类
|
||||
@@ -18,12 +31,75 @@ import java.lang.reflect.Field;
|
||||
@ConditionalOnClass(name = "org.springframework.amqp.rabbit.core.RabbitTemplate")
|
||||
public class ChenfengRabbitMQAutoConfiguration {
|
||||
|
||||
static {
|
||||
// 强制设置 SerializationUtils 的 TRUST_ALL 为 true,避免 RabbitMQ Consumer 反序列化消息报错
|
||||
// 为什么不通过设置 spring.amqp.deserialization.trust.all 呢?因为可能在 SerializationUtils static 初始化后
|
||||
Field trustAllField = ReflectUtil.getField(SerializationUtils.class, "TRUST_ALL");
|
||||
ReflectUtil.removeFinalModify(trustAllField);
|
||||
ReflectUtil.setFieldValue(SerializationUtils.class, trustAllField, true);
|
||||
/**
|
||||
* Jackson2JsonMessageConverter Bean:使用 jackson 序列化消息
|
||||
*/
|
||||
@Bean
|
||||
public MessageConverter createMessageConverter() {
|
||||
return new Jackson2JsonMessageConverter();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生产单导入交换机、队列、绑定声明
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public FanoutExchange orderImportFanoutExchange() {
|
||||
return new FanoutExchange(RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_EXCHANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产单导入队列声明
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue orderImportQueue() {
|
||||
Map<String, Object> args = new HashMap<>(1);
|
||||
// x-dead-letter-exchange 这里声明当前队列绑定的死信交换机
|
||||
args.put("x-dead-letter-exchange", ORDER_IMPORT_DEAD_LETTER_EXCHANGE);
|
||||
// 设置死信路由键
|
||||
args.put("x-dead-letter-routing-key", ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY);
|
||||
return QueueBuilder.durable(RabbitMqConstants.ORDER_IMPORT_DEFAULT_EXCEL_QUEUE).withArguments(args).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产单excel导入交换机声明
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Binding orderImportDefaultExcelBinding() {
|
||||
return BindingBuilder.bind(orderImportQueue()).to(orderImportFanoutExchange());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产单导入死信交换机声明
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public DirectExchange orderImportDeadLetterExchange(){
|
||||
return new DirectExchange(ORDER_IMPORT_DEAD_LETTER_EXCHANGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产单导入死信队列声明
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Queue orderImportDeadLetterQueue() {
|
||||
return new Queue(ORDER_IMPORT_DEAD_LETTER_QUEUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生产单导入死信队列、交换机、绑定声明
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
public Binding deadLetterBindingA() {
|
||||
return BindingBuilder.bind(orderImportDeadLetterQueue()).to(orderImportDeadLetterExchange()).with(ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.cf.imes.framework.mq.rabbitmq.constant;
|
||||
|
||||
/**
|
||||
* rabbitmq常量
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2025/1/6 11:15
|
||||
*/
|
||||
public class RabbitMqConstants {
|
||||
/**
|
||||
* 生产单导入交换机
|
||||
*/
|
||||
public static final String ORDER_IMPORT_DEFAULT_EXCEL_EXCHANGE = "order_import_default_excel_exchange";
|
||||
|
||||
/**
|
||||
* 生产单导入队列
|
||||
*/
|
||||
public static final String ORDER_IMPORT_DEFAULT_EXCEL_QUEUE = "order_import_default_excel_queue";
|
||||
|
||||
/**
|
||||
* 生产单导入死信交换机
|
||||
*/
|
||||
public static final String ORDER_IMPORT_DEAD_LETTER_EXCHANGE = "order_import_dead_letter_exchange";
|
||||
|
||||
/**
|
||||
* 生产单导入死信队列
|
||||
*/
|
||||
public static final String ORDER_IMPORT_DEAD_LETTER_QUEUE = "order_import_dead_letter_queue";
|
||||
|
||||
/**
|
||||
* 生产单导入死信路由键
|
||||
*/
|
||||
public static final String ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY = "order_import_dead_letter_routing_key";
|
||||
}
|
||||
+6
@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
|
||||
import com.baomidou.mybatisplus.extension.incrementer.*;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.cf.imes.framework.mybatis.core.injector.MybatisPlusInjector;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -75,4 +76,9 @@ public class ChenfengMybatisAutoConfiguration {
|
||||
throw new IllegalArgumentException("DbType为空");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInjector mybatisPlusInjector() {
|
||||
return new MybatisPlusInjector();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.cf.imes.framework.mybatis.core.injector;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 基础批量映射器
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2025/1/14 14:54
|
||||
*/
|
||||
public interface BaseBatchMapper<T> extends BaseMapper<T> {
|
||||
/**
|
||||
* 批量插入
|
||||
* 区别于mybatisplus的saveBatch:拼接(a,b,c,...)value(aval,bval,cval,...)而不是把多个insert一次性提交到数据库
|
||||
*
|
||||
* @param entityList
|
||||
* @return
|
||||
*/
|
||||
int insertBatchSomeColumn(List<T> entityList);
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.cf.imes.framework.mybatis.core.injector;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Gqr
|
||||
* @since 2025/1/14 14:46
|
||||
*/
|
||||
public class MybatisPlusInjector extends DefaultSqlInjector {
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
|
||||
return methodList;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.cf.imes.framework.mybatis.core.query;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
|
||||
/**
|
||||
* LambdaUpdateWrapper拓展
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2025/1/22 15:58
|
||||
*/
|
||||
public class LambdaUpdateWrapperX<T> extends LambdaUpdateWrapper<T> {
|
||||
public LambdaUpdateWrapperX<T> eqIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (ObjectUtil.isNotEmpty(val)) {
|
||||
return (LambdaUpdateWrapperX<T>) super.eq(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaUpdateWrapperX<T> eq(SFunction<T, ?> column, Object val) {
|
||||
super.eq(column, val);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -82,7 +82,7 @@ public class ChenfengCacheAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisLockUtil lockUtil(ChenfengCacheProperties chenfengCacheProperties, RedissonClient client) {
|
||||
return new RedisLockUtil(chenfengCacheProperties, client);
|
||||
public RedisLockUtil lockUtil(ChenfengCacheProperties chenfengCacheProperties, RedissonClient client, RedisTemplate redisTemplate) {
|
||||
return new RedisLockUtil(chenfengCacheProperties, client, redisTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -34,5 +34,5 @@ public class ChenfengCacheProperties {
|
||||
* 等待获取锁的时间,单位:毫秒(ms)
|
||||
* 默认0.5秒
|
||||
*/
|
||||
private int lockWaitTime = 500;
|
||||
private int lockWaitTime = 5000;
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.cf.imes.framework.redis.constants;
|
||||
|
||||
/**
|
||||
* 多模块公用redis key常量
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2025/1/14 15:22
|
||||
*/
|
||||
public class RedisKeyConstants {
|
||||
/**
|
||||
* 生产单导入
|
||||
*/
|
||||
public static final String ORDER_IMPORT_LOCK_KEY = "order_import:%s";
|
||||
}
|
||||
+37
@@ -6,6 +6,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.redisson.api.RLock;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -23,6 +24,8 @@ public class RedisLockUtil {
|
||||
|
||||
private RedissonClient redissonClient;
|
||||
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 加锁
|
||||
*
|
||||
@@ -63,6 +66,7 @@ public class RedisLockUtil {
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
* 使用注意:配合以上两个redisson的lock只能在当前线程中unlock,否则失败!!!
|
||||
*
|
||||
* @param key rediskey
|
||||
*/
|
||||
@@ -74,4 +78,37 @@ public class RedisLockUtil {
|
||||
log.error("[RedisLockUtil][unlock]解锁失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动set nx ex加锁
|
||||
* 使用注意:可用于跨服务
|
||||
*
|
||||
* @param key
|
||||
* @param uniqeKey 解锁的时候校验,避免其他任务误解
|
||||
* @param timeout
|
||||
* @return
|
||||
*/
|
||||
public boolean lock(String key, String uniqeKey, Integer timeout) {
|
||||
return redisTemplate.opsForValue().setIfAbsent(key, uniqeKey, timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
* 校验唯一值后删除key
|
||||
* 使用注意:可用于跨服务
|
||||
*
|
||||
* @param key
|
||||
* @param uniqeKey 解锁时校验,避免同key下其他任务解锁到
|
||||
*/
|
||||
public void unlock(String key, String uniqeKey) {
|
||||
Object object = redisTemplate.opsForValue().get(key);
|
||||
if (ObjectUtil.equal(object, uniqeKey)) {
|
||||
Boolean delete = redisTemplate.delete(key);
|
||||
if (delete) {
|
||||
log.info(String.format("[RedisLockUtil][unlock][%s]解锁", key));
|
||||
} else {
|
||||
log.error(String.format("[RedisLockUtil][unlock][%s]解锁失败", key));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<module>cf-spring-boot-starter-biz-organ</module>
|
||||
<module>cf-spring-boot-starter-biz-data-permission</module>
|
||||
<module>cf-spring-boot-starter-biz-error-code</module>
|
||||
<module>cf-spring-boot-starter-biz-id</module>
|
||||
<module>cf-spring-boot-starter-biz-ip</module>
|
||||
|
||||
<module>cf-spring-boot-starter-flowable</module>
|
||||
|
||||
Reference in New Issue
Block a user