• 售前

  • 售后

热门帖子
入门百科

mysql+mybatis实现存储过程+事务 + 多并发流水号获取

[复制链接]
放弃六月们 显示全部楼层 发表于 2022-1-9 07:39:46 |阅读模式 打印 上一主题 下一主题
数据库存储过程
  1. DROP PROCEDURE IF EXISTS `generate_serial_number_by_date`;
  2. CREATE PROCEDURE `generate_serial_number_by_date`(
  3.     IN param_key varchar(100),
  4.     IN param_org_id bigint,
  5.     IN param_period_date_format varchar(20),
  6.       OUT result bigint,
  7.     OUT current_datestr varchar(20))
  8. begin
  9.         declare old_datestr varchar(20);
  10.         
  11.         START TRANSACTION;
  12.         if param_period_date_format='infinite' then
  13.             set current_datestr = '00000000';
  14.     else
  15.             set current_datestr = DATE_FORMAT(NOW(), param_period_date_format);
  16.         end if;
  17.         
  18.         select
  19.                     number, datestr
  20.         from sys_serial_number
  21.         where table_key = param_key
  22.                 and org_id = param_org_id
  23.                 and period_date_format = param_period_date_format
  24.                 into result, old_datestr
  25.                 for update;
  26.         IF result is null then
  27.             
  28.             set result = 1;
  29.             
  30.             insert into sys_serial_number(table_key, org_id, period_date_format, datestr, number, description)
  31.                 values(param_key, param_org_id, param_period_date_format, current_datestr, 1, 'add by procedure');
  32.         
  33.         elseif old_datestr != current_datestr then
  34.             
  35.             set result = 1;
  36.             
  37.             update sys_serial_number
  38.                     set number = 1,   
  39.                             datestr = current_datestr
  40.             where table_key = param_key
  41.                     and org_id = param_org_id
  42.                     and period_date_format = param_period_date_format;
  43.             
  44.         end if;
  45.         
  46.         update sys_serial_number set number = number + 1
  47.             where table_key = param_key
  48.                 and org_id = param_org_id
  49.                 and period_date_format = param_period_date_format;
  50.     commit;
  51. end
复制代码
流水号表
  1. DROP TABLE IF EXISTS `sys_serial_number`;
  2. CREATE TABLE `sys_serial_number` (
  3.   `table_key` varchar(100) NOT NULL COMMENT '主键(建议用表名)',
  4.   `org_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '分公司ID',
  5.   `number` bigint(20) NOT NULL DEFAULT '1' COMMENT '流水号(存储过程控制递增,获取完后+1)',
  6.   `period_date_format` varchar(20) NOT NULL COMMENT '流水号生成周期日期格式',
  7.   `datestr` varchar(20) DEFAULT NULL COMMENT '流水号日期值',
  8.   `description` varchar(100) DEFAULT NULL COMMENT '描述',
  9.   PRIMARY KEY (`table_key`,`org_id`,`period_date_format`)
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='流水号生成表';
复制代码
mybatis配置
  1. <select id="generateSerialNumber" parameterType="java.util.HashMap" statementType="CALLABLE">
  2.     <![CDATA[
  3.            {
  4.            call generate_serial_number (
  5.             #{param_key,mode=IN,jdbcType=VARCHAR},
  6.             #{param_org_id,mode=IN,jdbcType=BIGINT},
  7.             #{result,mode=OUT,jdbcType=BIGINT}
  8.             )
  9.            }
  10.        ]]>
  11.   </select>
复制代码
测试代码
  1. @Override
  2.     public Map<String, Object> generateSerialNumber(Map<String, Object> param) {
  3.         sysSerialNumberMapper.generateSerialNumber(param);
  4.         return param;
  5.     }
复制代码
  1. final Map<String, Object> param = new HashMap<String, Object>();
  2.         param.put("param_key","contract");
  3.         param.put("param_orgId", 84);
  4.         new Thread(new Runnable() {
  5.             @Override
  6.             public void run() {
  7.                 for(int i =0; i<100; i++) {
  8.                     Map<String, Object> map = serialNumberProvider.generateSerialNumber(param);
  9.                     System.out.println("thread-1:" + map.get("result"));
  10.                 }
  11.             }
  12.         }).start();
  13.         new Thread(new Runnable() {
  14.             @Override
  15.             public void run() {
  16.                 for(int i =0; i<100; i++) {
  17.                     Map<String, Object> map = serialNumberProvider.generateSerialNumber(param);
  18.                     System.out.println("thread-2:" + map.get("result"));
  19.                 }
  20.             }
  21.         }).start();
  22.         new Thread(new Runnable() {
  23.             @Override
  24.             public void run() {
  25.                 for(int i =0; i<100; i++) {
  26.                     Map<String, Object> map = serialNumberProvider.generateSerialNumber(param);
  27.                     System.out.println("thread-3:" + map.get("result"));
  28.                 }
  29.             }
  30.         }).start();
  31.         byte[] b = new byte[0];
  32.         synchronized(b) {
  33.             b.wait();
  34.         }
复制代码
如果运行代码报以下错误
  1. ### SQL: {            call generate_serial_number_by_date (             ?,             ?,             ?,             ?,             ?            )            }### Cause: java.sql.SQLException: Parameter number 4 is not an OUT parameter; SQL []; Parameter number 4 is not an OUT parameter; nested exception is java.sql.SQLException: Parameter number 4 is not an OUT parameter
复制代码
排查方法:
1、查抄存储过程是否精确创建
2、查抄数据源连接用户是否有存储过程实行权限
到此这篇关于mysql+mybatis实现存储过程+事务 + 多并发流水号获取的文章就先容到这了,更多干系mysql mybatis存储过程流水号内容请搜刮脚本之家从前的文章或继承浏览下面的干系文章盼望各人以后多多支持脚本之家!

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作