思路:都是从缓存中取,取出来+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);
}
生成编码时处理并发+事务实际场景
提交工作单时,生成编码,保存提交数据
/**
* 提交工作任务单
*
* @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>