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

Implementation of modifying configuration files in Docker container

1. Enter the container docker run [option] image ...

HTML hyperlinks explained in detail

Hyperlink Hyperlinks are the most frequently used ...

The best way to start a jar package project under Centos7 server

Preface Everyone knows how to run a jar package o...

IDEA configuration process of Docker

IDEA is the most commonly used development tool f...

WeChat Mini Program Lottery Number Generator

This article shares the specific code of the WeCh...

Solve the problem of inconsistent MySQL storage time

After obtaining the system time using Java and st...

A brief discussion on the differences between FTP, FTPS and SFTP

Table of contents Introduction to FTP, FTPS and S...

Tutorial on installing MySQL 8.0.11 using RPM on Linux (CentOS7)

Table of contents 1. Installation preparation 1. ...

Implementation of React configuration sub-routing

1. The component First.js has subcomponents: impo...

Multiple methods to modify MySQL root password (recommended)

Method 1: Use the SET PASSWORD command MySQL -u r...

JavaScript implements constellation query function with detailed code

Table of contents 1. Title 2. Code 3. Results IV....