首页 > 数据库 >redis实现生成自增编码两种方式

redis实现生成自增编码两种方式

时间:2023-05-20 10:23:40浏览次数:54  
标签:编码 自增 return String redis value custWorkTaskInfoPO tnWorkTask ServiceResponse

redis实现生成自增编码两种方式

文章目录 https://blog.csdn.net/MS_SONG/article/details/130226992

 

思路:都是从缓存中取,取出来+1 再放入缓存,以便下次取用
区别:方式一,手动+1; 方式二:利用 redis.increment 实现自增;
提示:写业务代码时,记得加锁,锁中包含事务;

方式一


/**
* 生成经销商任务单号
*
* @param custTaskType 经销商任务单类型
* @return 结果
*/
@Override
public ServiceResponse generateCustTaskIdByTaskType(String custTaskType) {
if (StringUtils.isEmpty(custTaskType)){
return ServiceResponse.fail("经销商-传入空任务单类型!");
}
if (!(custTaskType.toUpperCase().equals(WorkTaskType.客户上市.value())
|| custTaskType.toUpperCase().equals(WorkTaskType.客户基础信息变更.value())
|| custTaskType.toUpperCase().equals(WorkTaskType.客户更名.value())
|| custTaskType.toUpperCase().equals(WorkTaskType.客户扩充.value())
|| custTaskType.toUpperCase().equals(WorkTaskType.基地对外客户上市.value()))){
return ServiceResponse.fail("经销商-传入任务单类型异常!");
}
// 生成编码
String custTaskId;
String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
String upCustTaskType = custTaskType.toUpperCase();
String custTaskNoKey = "cust:" + "work_task_no_key" + today + ":" + upCustTaskType;
Long taskSerialNo = Convert.toLong(redisTemplate.opsForValue().get(custTaskNoKey));
if (null != taskSerialNo){
taskSerialNo = taskSerialNo + 1L;
}else {
String firstCustTaskId = upCustTaskType + today + "0001";
if (null == tnWorkTaskMapper.selectTnWorkTaskByTaskId(firstCustTaskId)){
taskSerialNo = 1L;
}else {
// 缓存被意外删除
List<TnWorkTask> tnWorkTaskList = tnWorkTaskMapper.selectTnWorkTaskList(new TnWorkTask(){{ setTaskType(upCustTaskType);}});
List<Long> longList = new ArrayList<>();
tnWorkTaskList.stream().map(TnWorkTask::getTaskId).forEach(e -> longList.add( Convert.toLong(e.substring(12))));
Long lastTaskNo = longList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0);
taskSerialNo = lastTaskNo + 1L;
}
}
custTaskId = upCustTaskType + today + (taskSerialNo.toString().length() < 4 ? String.format("%04d", taskSerialNo) : taskSerialNo.toString());
// 校验
if (null != tnWorkTaskMapper.selectTnWorkTaskByTaskId(custTaskId)){
return ServiceResponse.fail("经销商-生成任务单号已存在!");
}
redisTemplate.opsForValue().set(custTaskNoKey, taskSerialNo, getSeconds(), TimeUnit.SECONDS);
return ServiceResponse.success(custTaskId);
}

/**
* 获取当天结束还剩余多少秒
* @return
*/
public static int getSeconds(){
Calendar curDate = Calendar.getInstance();
Calendar tommorowDate = new GregorianCalendar(
curDate.get(Calendar.YEAR),
curDate.get(Calendar.MONTH),
curDate.get(Calendar.DATE) + 1,
0, 0, 0);
return (int)(tommorowDate.getTimeInMillis() - curDate.getTimeInMillis()) / 1000;
}

 

方式二

 


/**
* 生成经销商客户编码
*
* @param
* @return 结果
*/
@Override
public ServiceResponse generateCustAccCode() {
String accCodeKey = "cust:" + "account_code_no_key" ;
Integer accCode = (Integer) redisTemplate.opsForValue().get(accCodeKey);
if (null == accCode)
{
List<String> accCodes = tnMdCustBaseMapper.selectTnMdCustBaseList(null).stream().map(TnMdCustBase::getAcctCode).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(accCodes)){
List<Integer> codeList = new ArrayList<>();
accCodes.forEach(e -> codeList.add(Integer.parseInt(e)));
Integer lastAccCode = codeList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0);
redisTemplate.opsForValue().set(accCodeKey, lastAccCode);
}
}
accCode = Math.toIntExact(redisTemplate.opsForValue().increment(accCodeKey, 1));
// 校验
Integer finalAccCode = accCode;
if (!CollectionUtils.isEmpty(tnMdCustBaseMapper.selectTnMdCustBaseList(new TnMdCustBase(){{ setAcctCode(finalAccCode.toString());}}))){
return ServiceResponse.fail("生成失败,客户编码已存在!");
}
return ServiceResponse.success(finalAccCode);
}

 

 推荐:
高并发redis自增increment使用

生成编码时处理并发+事务实际场景

提交工作单时,生成编码,保存提交数据

/**
* 提交工作任务单
*
* @param custWorkTaskInfoPO
* @return
*/
public ServiceResponse submitCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO);

/**
* 保存任务单详情
*
* @param custWorkTaskInfoPO
* @return 结果
*/
public ServiceResponse saveCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO);

/**
* 处理工作任务单
*
* @param tnWorkTask
* @return 结果
*/
public ServiceResponse handleCustCTDJWorkTask(TnWorkTask tnWorkTask) throws Exception;

/**
* 处理任务单详情
*
* @param custWorkTaskInfoPO
* @return 结果
*/
public int handleCTDJCustWorkInfoDetail(CustWorkTaskInfoPO custWorkTaskInfoPO);

/**
* 生成经销商任务单号
*
* @param custTaskType 经销商任务单类型
* @return 结果
*/
public ServiceResponse generateCustTaskIdByTaskType(String custTaskType);

 

 

//

 

@Override
@Transactional(rollbackFor = Exception.class)
public ServiceResponse submitCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO){
ServiceResponse serviceResponse;
try {
serviceResponse = saveCTDJCustWorkInfo(custWorkTaskInfoPO);
} catch (Exception e) {
e.printStackTrace();
log.warn("经销商-客户冻结-提交时保存异常", e);
throw new RuntimeException(e);
}
if (serviceResponse.ok()){
String taskId = custWorkTaskInfoPO.getTnWorkTask().getTaskId();
try {
// 提交oa
return ServiceResponse.success("经销商-客户冻结-提交OA成功" + taskId);
} catch (Exception e) {
e.printStackTrace();
log.warn("经销商-客户冻结-提交OA时异常", e);
throw new RuntimeException(e);
}
}
return serviceResponse;
}

 


@Override
@Transactional(rollbackFor = Exception.class)
public ServiceResponse saveCTDJCustWorkInfo(CustWorkTaskInfoPO custWorkTaskInfoPO) {
ServiceResponse workTaskResponse = handleCustCTDJWorkTask(custWorkTaskInfoPO.getTnWorkTask());
if (workTaskResponse.ok()){
if (handleCTDJCustWorkInfoDetail(custWorkTaskInfoPO) == custWorkTaskInfoPO.getTnMdCustTempBusiScopes().size()){
return ServiceResponse.success(custWorkTaskInfoPO.getTnWorkTask().getTaskId());
}
}
return workTaskResponse;
}

 

 

@Override
public ServiceResponse handleCustCTDJWorkTask(TnWorkTask tnWorkTask) {
try {
redisLock.lock("CTDJ");
String user = SecurityUtils.getLoginUser().getUsername();
Date now = DateUtils.getNowDate();
if (StringUtils.isEmpty(tnWorkTask.getTaskId())){
ServiceResponse response = generateCustTaskIdByTaskType(WorkTaskType.客户冻结.value());
if (response.ok()){
tnWorkTask.setTaskId((String) response.getData());
}else {
return response;
}
tnWorkTask.setTaskType(WorkTaskType.客户冻结.value());
tnWorkTask.setApplicantId(user);
tnWorkTask.setApplyTime(now);
tnWorkTask.setCreateBy(user);
tnWorkTask.setCreateTime(now);
log.info("经销商-客户冻结-新增任务单{}",tnWorkTask);
return ServiceResponse.success(tnWorkTaskMapper.insertTnWorkTask(tnWorkTask));
}else {
tnWorkTask.setUpdateBy(user);
tnWorkTask.setUpdateTime(now);
log.info("经销商-客户冻结-更新任务单{}",tnWorkTask);
return ServiceResponse.success(tnWorkTaskMapper.updateTnWorkTask(tnWorkTask));
}
} catch (Exception e) {
e.printStackTrace();
log.warn("经销商-客户冻结-处理任务单异常", e);
} finally {
redisLock.unlock("CTDJ");
}
return ServiceResponse.fail("经销商-客户冻结-处理任务单失败");
}

 


@Override
@Transactional(rollbackFor = Exception.class)
public int handleCTDJCustWorkInfoDetail(CustWorkTaskInfoPO custWorkTaskInfoPO){
try {
int affectRows = 0;
Date now = DateUtils.getNowDate();
String user = SecurityUtils.getLoginUser().getUsername();
String taskId = custWorkTaskInfoPO.getTnWorkTask().getTaskId();
custWorkTaskInfoPO.getTnMdCustTempBusiScopes().forEach(e -> {
e.setApplyNo(taskId);
e.setApplyType(WorkTaskType.客户冻结.value());
e.setStatus(CustDataStatusInteger.NORMAL.value()); //记录状态:10正常 5作废
e.setCreateBy(user);
e.setCreateTime(now);
});
if (!CollectionUtils.isEmpty(custWorkTaskInfoPO.getTnMdCustTempBusiScopes())){
for (TnMdCustTempBusiScope tnMdCustTempBusiScope : custWorkTaskInfoPO.getTnMdCustTempBusiScopes()) {
affectRows += tnMdCustTempBusiScopeMapper.insertTnMdCustTempBusiScope(tnMdCustTempBusiScope);
}
}
return affectRows;
}catch (Exception e){
e.printStackTrace();
log.error("处理任务单行信息异常", e);
throw new RuntimeException(e);
}
}


/**
* 生成经销商任务单号
*
* @param custTaskType 经销商任务单类型
* @return 结果
*/
@Override
public ServiceResponse generateCustTaskIdByTaskType(String custTaskType) {
if (StringUtils.isEmpty(custTaskType)){
return ServiceResponse.fail("经销商-传入空任务单类型");
}
if (!checkIsCustWorkTaskType(custTaskType)){
return ServiceResponse.fail("经销商-传入任务单类型异常");
}
String custTaskId;
try {
String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
String prefix = custTaskType.toUpperCase() + today ;
String maxTaskId = tnWorkTaskMapper.selectTodayMaxWorkTaskId(prefix);
custTaskId = StringUtils.isEmpty(maxTaskId) ? prefix + String.format("%04d", 1) : prefix + String.format("%04d", Long.parseLong(maxTaskId.substring(12)) + 1L);
}catch (Exception e){
e.printStackTrace();
return ServiceResponse.fail("经销商-任务单号生成异常");
}
return ServiceResponse.success(custTaskId);
}

private boolean checkIsCustWorkTaskType(String taskType) {
if (taskType.toUpperCase().equals(WorkTaskType.客户上市.value())
|| taskType.toUpperCase().equals(WorkTaskType.客户基础信息变更.value())
|| taskType.toUpperCase().equals(WorkTaskType.客户更名.value())
|| taskType.toUpperCase().equals(WorkTaskType.客户扩充.value())
|| taskType.toUpperCase().equals(WorkTaskType.客户冻结.value())
|| taskType.toUpperCase().equals(WorkTaskType.客户解冻.value())
|| taskType.toUpperCase().equals(WorkTaskType.基地对外客户上市.value())){
return true;
}
return false;
}

 查询今天任务单类型对应的编码号

/**
* 查询申请工作单列表最大的任务单号
*
* @param prefix 当天任务单前缀
* @return 申请工作单集合
*/
public String selectTodayMaxWorkTaskId(@Param(value = "prefix") String prefix);

 

<select id="selectTodayMaxWorkTaskId" parameterType="String" resultType="java.lang.String">
SELECT max(task_id) from tn_work_task where task_id like concat( #{prefix}, '%')
</select>

 

标签:编码,自增,return,String,redis,value,custWorkTaskInfoPO,tnWorkTask,ServiceResponse
From: https://www.cnblogs.com/chuangsi/p/17416834.html

相关文章

  • Redis笔记(三):事务
    什么是Redis事务Redis事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。总结说:redis事务就是一次性、顺序性、排他性的执行一个......
  • Java编程进阶:掌握这五个高级特性让编码更得心应手
    当今,在软件开发中最流行和使用最广泛的语言之一是Java。Java不仅是一种面向对象的编程语言,还可以用于Web开发、移动应用程序编程、云计算和大数据处理。如果你是一个初学者,或者是想要进一步了解Java编程的高级特性,那么这篇文章会帮助你更好地了解Java编程。一、使用lambda表达式在J......
  • Redis笔记(二):三种特殊类型
    geospatial地理位置GEOADDkey[NX|XX][CH]longitudelatitudemember[longitudelatitudemember...]地球两极无法直接添加经度纬度GEODIST#单位m,km,mi,ftGEOHASHGEOPOSGEORADIUSGEORADIUSBYMEMBERJava中的数据结构......
  • 开发手记:Redis中zset查询的range
    问题描述从Redis中查询关注列表(使用zset存储),但是查询到的记录总是比应有的记录数少一个Set<Integer>targetIds=redisTemplate.opsForZSet().reverseRange(key,offset,offset+limit-1);调试于是去检查Redis中置顶键zset中的所有数据,发现自己对zset相关命令似乎并不太......
  • Android平台外部编码数据(H264/H265/AAC/PCMA/PCMU)实时预览播放技术实现
    开发背景好多开发者可能疑惑,外部数据实时预览播放,到底有什么用?是的,一般场景是用不到的,我们在开发这块前几年已经开发了非常稳定的RTMP、RTSP直播播放模块,不过也遇到这样的场景,部分设备输出编码后(视频:H.264/H.265,音频:AAC/PCMA/PCMU)的数据,比如无人机或部分智能硬件设备,回调出来的H.26......
  • Docker容器安装示例(nginx、redis、nacos、oracle)
    1.nginx示例1.创建容器1.查看是否有nginx镜像dockerimages2.如果没有镜像,可以搜索镜像dockersearchnginx3.指定版本拉取nginxdockerpullnginx:1.20.04.查看镜像dockerimages5.创建容器(-d后台运行,-p容器80端口映射到宿主机8080端口,指定名称nginx-test,指定镜像ID:......
  • Redis学习手册(持久化)
    一、Redis提供了哪些持久化机制:   1).RDB持久化:   该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。       2).AOF持久化:   该机制将以日志的形式记录服务器所处理的每一个写操作,在Redis服务器启动之初会读取该文件来重新构建数据库,以保证启动......
  • k8s快速部署Redis单机
    1.创建Redis配置apiVersion:v1data:redis.conf:|-bind0.0.0.0port6379requirepassSystem@123pidfile/var/run/redis_6379.pidsave9001save30010save6010000rdbcompressionyesrdbchecksumyesdbfilenamedum......
  • IDEA 编码格式设置 UTF-8
    IDEA编码格式设置UTF-81.文件编码设置为UTF-82.编译编码设置为utf-83.虚拟机自定义设置(一般可不设置) 1.文件编码设置为UTF-8Editor>FileEncodings 2.编译编码设置为utf-8Build,Execution,Deployment>Complier>JavaComplier按图中设置:-encodingutf-8 3.......
  • java面试题--Redis
    一、说一下redis的持久化机制原理?RDB文件:redisdatabase。存储的是某个时间点的数据库内容的快照,是结果。redis默认的持久化策略。落盘策略:使用SAVE或者BGSAVE命令。(1)SAVE:有主线程执行,会阻塞客户端。(2)BGSAVE:会fork出一个子进程,不会出现阻塞问题。子进程使用写时拷贝的策......