编号根据规则自增生成,及spring事务和锁

news2024/9/17 8:29:25

1、 背景

需要根据一些规则来生成自增编号,比如:95JS0001,950002
95JS是固定的,而后缀的0001的长度也是可配置的,因为有一张表来进行维护


CREATE TABLE `number_control` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `number_category` varchar(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '编号类别',
  `number_type` char(2) COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '0为微机编号,1为人工编号',
  `is_department_number` char(2) COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '是否开启单位号,默认开启',
  `project_num` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '项目号',
  `is_year` char(2) COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '是否开启年份,默认开启',
  `is_month` char(2) COLLATE utf8mb4_general_ci DEFAULT '1' COMMENT '是否开启月份,默认开启',
  `divide_sign` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分隔符号',
  `digit` int DEFAULT '1' COMMENT '位数,默认为1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2181 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='编号管理表';

为了方便编号的查询,于是又维护另一张表来存储生成编号的进度

CREATE TABLE `generate_number` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `prefix` varchar(100) DEFAULT NULL COMMENT '前缀,根据编号规则生成的前缀',
  `number` bigint DEFAULT '1' COMMENT '记录生成的号码',
  `number_category` char(2) DEFAULT NULL COMMENT '编号类别',
  `digit` int DEFAULT NULL COMMENT '位数'
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='记录编号生成表';

因为要求编号必须连续且自增,所以必然要使用到锁,这里使用的是ReentrantLock,因为涉及到多张表的查看及更新,也用到了事务,因为锁和事务,遇到了一些问题

2、解决

先说解决方案,遇到的问题放在第三点,想看的可以看看
首先参考这篇章
https://blog.csdn.net/zzhongcy/article/details/103583008
写了一个切面,但要注意的是必须要加@order注解,否则锁不住。
另外要把切面的catch去掉,将异常抛出,否则事务会失效

@Component
@Aspect
@Order(1)
public class LockAspect {

    private  final Lock lock = new ReentrantLock();

    @Pointcut("@annotation(Servicelock)")
    public void lockAspect() {}

    @Around("lockAspect()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        lock.lock();
        Object obj;
        //catch会导致事务失效,所以抛出异常
        try {
            obj = joinPoint.proceed();
        }
        finally {
            lock.unlock();
        }
        return obj;
    }
}

3、思路及解决步骤

3.1、首先我想的是直接写一个工具类,让其他人调用生成编号的

  public String getNumber(Long reportId, String category) {
        NumberControl numberControl = numberControlManage.selectByReportIdAndNumberCategory(reportId, category);
        if (numberControl != null) {
            //人工编号返回null
            if (ConstantPool.ONE.toString().equals(numberControl.getNumberType())) {
                return null;
            }

            Integer digit = numberControl.getDigit();
            String predix = generatePrefix(numberControl);

           
            lock.lock();
            try {
                //去生成编号中查询一下
                GenerateNumber generateNumber = generateNumberManage.getByPrefixAndCategory(predix, category, digit);
                //说明没有
                if (generateNumber == null) {
                    generateNumber = new GenerateNumber();
                    generateNumber.setPrefix(predix);
                    generateNumber.setNumberCategory(category);
                    generateNumber.setDigit(digit);
                    generateNumberManage.save(generateNumber);
                    return predix + formatNumber(digit, 1);
                } else {
                    Long number = generateNumber.getNumber() + 1;
                    generateNumber.setNumber(number);
                    generateNumberManage.updateById(generateNumber);
                    return predix + formatNumber(digit, number.intValue());
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                lock.unlock();
            }

        }
        return null;
    }

这里直接使用ReentrantLock锁住,但是当上层方法加上事务的时候,会导致锁失效。
简单来说就是:事务还未提交的时候,锁已经释放了

   @Transactional(rollbackFor = Exception.class)
    public R<Boolean> copy(EntrustCopyDto dto) {
        EntrustSamples byId = entrustSamplesManage.getById(dto.getId());
        //将id置为空
        byId.setId(null);

        String number;
        if (ConstantPool.YES.toString().equals(dto.getPreEntrust())) {
        //这里走完锁就会被释放掉,而事务还未被提交
            number = numberControlService.getNumber(byId.getCheckProjectId(), NumberCategoryEnum.PREENTRUST.getCode());
        } else {
            number = numberControlService.getNumber(byId.getCheckProjectId(), NumberCategoryEnum.ENTRUST.getCode());
        }
        byId.setCommissionNumber(number);
        return R.ok(entrustSamplesManage.save(byId));
    }

3.2、发现上面这样写不行,改成切面方式

https://blog.csdn.net/zzhongcy/article/details/103583008
当然也有其他方式,可参考
https://blog.csdn.net/small_love/article/details/127263276
按理说,这样应该可以了,但是发现还是锁不住

3.3、添加@order

因为看文章提到了@order,抱着死马当活马医的心态加上去了,结果竟然好了。不信邪,又去掉@order压测,加上@order压测尝试了好几遍,发现加上去之后确实可以。
于是之后就开始查找原因,之前看文章说@Transactional的默认优先级就是Integer.MAX_VALUE,数字越大优先级越低,想着默认的怎么也不至于比它优先级还低吧。。。。
结果还真是一样低。
首先进去@order注解,发现是通过这个类来进行比较优先级别的
在这里插入图片描述
然后进去该类,翻译
在这里插入图片描述
大体就是这样了,折腾了很久。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1918260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DW03D是一款用于锂离子/聚合物电池保护的高集成度解决方案。DW03D包含内部功率MOSFET、高精度电压检测电路和延迟电路

一般概述 DW03D产品是单节锂离子/锂聚合物可充电电池组保护的高集成度解决方案。DW03D包括了先进的功率MOSFET&#xff0c;高精度的电压检测电路和延时电路。 DW03D具有非常小的TSS08-8的封装,这使得该器件非常适合应用于空间限制得非常小的可充电电池组应用。…

生信软件25 - 三代测序数据灵敏比对工具ngmlr

1. ngmlr简介 CoNvex Gap-cost Ments for Long Reads&#xff08;ngmlr&#xff09;是一种长reads比对工具&#xff0c;可以将PacBio或Oxford Nanopore灵敏地与&#xff08;大&#xff09;参考基因组&#xff08;比如人类参考基因组&#xff09;对齐&#xff0c;能快速和正确地…

OpenSSH Server远程代码执行漏洞 (CVE-2024-6387)|centos7升级到最新版本OpenSSH-9.8.p1

一、漏洞概述 漏洞名称 OpenSSH Server远程代码执行漏洞 CVE ID CVE-2024-6387 漏洞类型 竞争条件 发现时间 2024-07-01 漏洞评分 暂无 漏洞等级 高危 攻击向量 网络 所需权限 无 利用难度 高 用户交互 无 PoC/EXP 未公开 在野利用 未发现 OpenS…

MechMind结构光相机 采图SDK python调用

测试效果 Mech-Mind结构光相机 Mech Mind&#xff08;梅卡曼德&#xff09;的结构光相机&#xff0c;特别是Mech-Eye系列&#xff0c;是工业级的高精度3D相机&#xff0c;广泛应用于工业自动化、机器人导航、质量检测等多个领域。以下是对Mech Mind结构光相机的详细解析&#…

阿里巴巴国际站携手NBA传奇托尼·帕克,中国卖家又一波利好!

在全球化浪潮日益汹涌的今天&#xff0c;跨界合作已成为推动品牌国际化进程的重要力量。近日&#xff0c;阿里巴巴国际站宣布了一项震撼业界的合作——正式签约NBA&#xff08;美国职业篮球联赛&#xff09;传奇控球后卫托尼帕克&#xff08;Tony Parker&#xff09;作为其全球…

2024年10款免费的项目管理软件推荐

本文向大家推荐10款2024年免费使用的项目管理软件&#xff0c;其中包括桌面应用和基于Web平台的多种产品&#xff0c;同时还涵盖了一些优秀的开源软件。 1.禅道开源项目管理软件 禅道是一款开源的、基于Web的项目管理软件&#xff0c;其功能丰富且操作简便&#xff0c;为团队提…

生产管理系统功能全拆解:哪些功能是企业真正需要的?

制造业的伙伴经常听到“生产管理”&#xff0c;但很多人可能只是模糊地知道它与工厂、生产线有关。那么&#xff0c;到底什么是生产管理呢&#xff1f;它的重要性又体现在哪里呢&#xff1f;接下来&#xff0c;我就以轻松的方式&#xff0c;带大家走进生产管理的世界&#xff0…

笔记:Qt开发之工程的多模块设计(pri)

目标&#xff1a;对于功能模块较多的Qt项目&#xff0c;使用pri文件管理模块文件&#xff0c;降低工程复杂度&#xff0c;提高软件模块的封装性和重用性。 一、知识储备 1.1 pro与pri文件 对于模块化编程&#xff0c;Qt提供了pro和pri&#xff0c;pro管理项目&#xff0c;pri…

算法 —— 模拟

目录 替换所有的问号 提莫攻击 Z字形变换 外观数列 各位读者有听说过“建模”一词吗&#xff1f;所谓“建模”&#xff0c;就是把事物进行抽象&#xff0c;根据实际问题来建立对应的数学模型。“抽象”并不意味着晦涩难懂&#xff1b;相反&#xff0c;它提供了大量的便利。…

新兴商业模式如何破局?市场策划专家的实战指南

在这个融合了传统市场、互联网和信息技术的大潮中&#xff0c;想要在市场营销策划上玩得转&#xff0c;咱们得有超凡的全局思维和跨界的协作精神。 下面&#xff0c;我就来和大家聊聊如何在这样一个复杂环境下搞定市场营销策划&#xff0c;让你在竞争激烈的市场中脱颖而出。 …

Ubuntu编译PX4固件

目录 前言 准备编译参考 前言 要想自己编译PX4固件需要交叉编译器&#xff0c;交叉编译器可以将 x86架构 平台上写好程序编译出来&#xff0c;而编译出来的可执行文件是能用到 arm架构 的平台上。 本次编译是以 px4 v1.13.2 为例。 我的配置如下&#xff1a; 虚拟机 Ubuntu 18…

微气象仪的工作原理

型号推荐&#xff1a;云境天合TH-WQX5】风力发电传感器在风力发电系统中起着至关重要的作用&#xff0c;它们能够实时监测和记录各种关键参数&#xff0c;为风力发电机组的控制提供数据支持&#xff0c;从而确保风力发电系统的安全、高效运行。以下是对风力发电传感器的详细解析…

喜讯|华院计算法律大模型入围《2024大模型典型示范应用案例集》

2024年世界人工智能大会&#xff08;WAIC&#xff09;举办期间&#xff0c;中国信通院正式发布了《2024大模型典型示范应用案例集》&#xff08;以下简称《案例集》&#xff09;。该案例集由中国信通院华东分院、上海人工智能实验室主导&#xff0c;以产业化为导向&#xff0c;…

Vue从零到实战第一天

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

免费分享:中国冬小麦地图数据集(附下载方法)

小麦按播种和收获季节的不同&#xff0c;可分为春小麦和冬小麦两种。春小麦颗粒长而大&#xff0c;皮厚色泽深&#xff0c;蛋白质含量高&#xff0c;但筋力较差&#xff0c;出粉率低&#xff0c;吸水率高;冬小麦颗粒小&#xff0c;吸水率低&#xff0c;蛋白质含量较春小麦少&am…

element-plus 按需导入问题 404等问题

场景 新开一个项目&#xff0c;需要用element-plus这个ui库&#xff0c;使用按需引入。 这是我项目的一些版本号 "element-plus": "^2.7.6","vue": "^3.2.13","vue-router": "^4.0.3",过程&#xff08;看解决方法…

电商、物流必备神器!容联七陌OCR精准识别、一键复制关键信息!

随着大模型、AI技术的快速发展及落地运用&#xff0c;传统的数据处理方式难以满足企业、行业需求&#xff0c;例如一字一句输入效率低、文字复制方式繁琐且容易出错、截图关键信息提取的准确性和高效性、缺乏信息智能识别能力等。 OCR识别技术能够快速准确地将图片中的文字信息…

【Linux】进程的基本概念(以及进程地址空间的初步了解)

目录 一.什么是进程 进程和程序的区别 Linux查看进程 进程的信息 fork函数 二.进程状态 操作系统上进程状态的概念 运行 阻塞 挂起 Linux中的进程状态 R状态 S状态和D状态 T状态 t状态 X状态 Z状态 三.进程的优先级 修改进程优先级 四.环境变量 常见的环境变量 PATH HOME PW…

行列视(RCV)报表是如何产生的?

首先看一下对于生产型企业来说&#xff0c;生产数据特点是什么样的&#xff1a; 生产数据可以理解为是生产制造企业&#xff0c;在生产过程中从车间现场设备上通过自动化传感器采集到的全面感知数据。这类数据一般包括设备状态、设备管道运行参数、各种仪表参数等。具有持续、…

【Linux操作系统-测试】第三节.Linux 系统、网络信息、用户权限命令总结

文章目录 前言一、Linux 系统相关信息命令 1.1 df 命令--查看磁盘剩余 1.2 ps 命令--查看进程 1.3 top 命令--显示进程运行状态 1.4 kill 命令说明 -- 杀死进程二、Linux 网络信息命令 2.1 ping 命令--检查网络是否连通 2.1 ifconfig--显示网络设…