MYSQL SEQUENCE方案

方案1:

-- 建表
CREATE TABLE TB_SEQ (
    SEQ_KEY INT         NOT NULL                    COMMENT 'key',
    UPTIME  datetime    DEFAULT CURRENT_TIMESTAMP   COMMENT '更新时间',
    NAME    VARCHAR(32)                             COMMENT '名称',
    VALUE   BIGINT      DEFAULT 1                   COMMENT '序列值',
    STEP    BIGINT      DEFAULT 1                   COMMENT '步长',
    PRIMARY KEY (`SEQ_KEY`)
);


-- 方式1(函数): 
-- 注:本方案存在并发问题,@val1非原子性,可能返回重复值)
DROP FUNCTION F_NEXTVAL;

CREATE FUNCTION F_NEXTVAL (seqKey int, seqName varchar(32))
RETURNS bigint
BEGIN
    
    -- 当前值自增长步长1
    UPDATE TEST.TB_SEQ SET VALUE = (@val1 := VALUE + STEP) WHERE SEQ_KEY = seqKey;

    -- 返回自增长之后的值
    RETURN @val1;

END;


-- 方式2(存储过程): 
-- 注:本方案事务保障并发,无重复值
DROP PROCEDURE P_NEXTVAL;

CREATE PROCEDURE P_NEXTVAL(seqKey int, seqName varchar(32))
BEGIN
  DECLARE val1 bigint default -1;

    -- 启用事务(RR)
    START TRANSACTION;
        
        -- 当前值自增长步长1
        UPDATE TEST.TB_SEQ SET VALUE = VALUE + STEP WHERE SEQ_KEY = seqKey;
            
        SELECT VALUE INTO val1 FROM TEST.TB_SEQ WHERE SEQ_KEY = seqKey;

    COMMIT;

    SELECT val1;

END

-- 方式2延伸(java代码控制事务 mybatis): 
-- 注:本方案事务保障并发,无重复, 切忌执行当前sql,需要开启单独事务并提交

       
    -- 当前值自增长步长1
    UPDATE TEST.TB_SEQ SET VALUE = VALUE + STEP WHERE SEQ_KEY = seqKey;
    
                
        SELECT VALUE INTO val1 FROM TEST.TB_SEQ WHERE SEQ_KEY = seqKey;
    



END

方案2:

-- 建表
CREATE TABLE TB_SEQ (
    SEQ_KEY INT         NOT NULL  AUTO_INCREMENT    COMMENT 'key',
    PRIMARY KEY (`SEQ_KEY`)
);


-- 通过事务控制,获取最新last_insert_id();
-- 可以使用方式1中的 存储过程或者事务逻辑处理
-- 副作用:会产生大量无用记录, 可定期删除清理
start transaction;

insert into TB_SEQ values();
select last_insert_id(); 

commit;

 

你可能感兴趣的:(数据库,mysql,mysql,数据库)