mysql+mybatis implements stored procedure + transaction + multi-concurrent serial number acquisition

mysql+mybatis implements stored procedure + transaction + multi-concurrent serial number acquisition

Database stored procedures

 DROP PROCEDURE IF EXISTS `generate_serial_number_by_date`;
CREATE PROCEDURE `generate_serial_number_by_date`(
    IN param_key varchar(100),
    IN param_org_id bigint, 
    IN param_period_date_format varchar(20), 
      OUT result bigint,
    OUT current_datestr varchar(20))
begin 

        declare old_datestr varchar(20);
        
        START TRANSACTION; 

        if param_period_date_format='infinite' then 
            set current_datestr = '00000000';
    else
            set current_datestr = DATE_FORMAT(NOW(), param_period_date_format);
        end if;
        
        select 
                    number, datestr 
        from sys_serial_number
        where table_key = param_key 
                and org_id = param_org_id 
                and period_date_format = param_period_date_format
                into result, old_datestr
                for update;

        IF result is null then
            
            set result = 1;
            
            insert into sys_serial_number(table_key, org_id, period_date_format, datestr, number, description) 
                values(param_key, param_org_id, param_period_date_format, current_datestr, 1, 'add by procedure');
        
        elseif old_datestr != current_datestr then
            
            set result = 1;
            
            update sys_serial_number 
                    set number = 1,    
                            datestr = current_datestr 
            where table_key = param_key 
                    and org_id = param_org_id 
                    and period_date_format = param_period_date_format;
            
        end if;
        
        update sys_serial_number set number = number + 1 
            where table_key = param_key 
                and org_id = param_org_id 
                and period_date_format = param_period_date_format;
    commit;
end

Serial number table

DROP TABLE IF EXISTS `sys_serial_number`;
CREATE TABLE `sys_serial_number` (
  `table_key` varchar(100) NOT NULL COMMENT 'Primary key (table name is recommended)',
  `org_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Branch ID',
  `number` bigint(20) NOT NULL DEFAULT '1' COMMENT 'Serial number (incremented by the stored procedure, +1 after acquisition)',
  `period_date_format` varchar(20) NOT NULL COMMENT 'Serial number generation period date format',
  `datestr` varchar(20) DEFAULT NULL COMMENT 'Serial number date value',
  `description` varchar(100) DEFAULT NULL COMMENT 'Description',
  PRIMARY KEY (`table_key`,`org_id`,`period_date_format`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Serial number generation table';

mybatis configuration

<select id="generateSerialNumber" parameterType="java.util.HashMap" statementType="CALLABLE">
    <![CDATA[
           {
           call generate_serial_number (
            #{param_key,mode=IN,jdbcType=VARCHAR},
            #{param_org_id,mode=IN,jdbcType=BIGINT},
            #{result,mode=OUT,jdbcType=BIGINT}
            )
           }
       ]]>
  </select>

Test code

@Override
    public Map<String, Object> generateSerialNumber(Map<String, Object> param) {
        sysSerialNumberMapper.generateSerialNumber(param);
        return param;
    }
final Map<String, Object> param = new HashMap<String, Object>();
        param.put("param_key","contract");
        param.put("param_orgId", 84);
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i =0; i<100; i++) {
                    Map<String, Object> map = serialNumberProvider.generateSerialNumber(param);
                    System.out.println("thread-1: " + map.get("result"));
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i =0; i<100; i++) {
                    Map<String, Object> map = serialNumberProvider.generateSerialNumber(param);
                    System.out.println("thread-2: " + map.get("result"));
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i =0; i<100; i++) {
                    Map<String, Object> map = serialNumberProvider.generateSerialNumber(param);
                    System.out.println("thread-3: " + map.get("result"));
                }
            }
        }).start();

        byte[] b = new byte[0];
        synchronized(b) {
            b.wait();
        }

If you run the code and get the following error

### 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

Troubleshooting method:

1. Check whether the stored procedure is created correctly

2. Check whether the data source connection user has the stored procedure execution permission

This is the end of this article about mysql+mybatis to implement stored procedure + transaction + multi-concurrent serial number acquisition. For more relevant mysql mybatis stored procedure serial number content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Example of using MySQL transaction features to implement concurrent and safe auto-increment ID
  • Solution to PHP+MySQL high-concurrency locked transaction processing problem
  • Can MySQL's repeatable read level solve phantom reads?
  • Detailed explanation of how MySQL solves phantom reads
  • Mysql transaction concurrency problem solution
  • Detailed explanation of MySQL phantom reads and how to eliminate them
  • MySQL Series 10 MySQL Transaction Isolation to Implement Concurrency Control
  • How to solve the phantom read problem in MySQL
  • Detailed explanation of concurrent dirty read + non-repeatable read + phantom read in Mysql transactions

<<:  How to Choose the Perfect Aloe Vera Gel? Perfect Aloe Vera Gel How to Identify Authenticity and Fakeness

>>:  Image scrolling effect made with CSS3

Recommend

HTML basic summary recommendation (title)

HTML: Title Heading is defined by tags such as &l...

How to set mysql5.7 encoding set to utf8mb4

I recently encountered a problem. The emoticons o...

Ubuntu 18.04 MySQL 8.0 installation and configuration method graphic tutorial

This article shares the installation and configur...

mysql5.6.zip format compressed version installation graphic tutorial

Preface: MySQL is a relational database managemen...

Mysql inner join on usage examples (must read)

Grammatical rules SELECT column_name(s) FROM tabl...

Example of troubleshooting method to solve Nginx port conflict

Problem Description A Spring + Angular project wi...

MySQL installation and configuration method graphic tutorial (CentOS7)

1. System environment [root@localhost home]# cat ...

Linux checkup, understand your Linux status (network IO, disk, CPU, memory)

Table of contents 1. Core commands 2. Common comm...

CSS pseudo-element::marker detailed explanation

This article will introduce an interesting pseudo...

HTML table tag tutorial (17): table title vertical alignment attribute VALIGN

The table caption can be placed above or below th...

503 service unavailable error solution explanation

1. When you open the web page, 503 service unavai...

How does Vue implement communication between components?

Table of contents 1. Communication between father...

How to dynamically add ports to Docker without rebuilding the image

Sometimes you may need to modify or add exposed p...