mysql 实现sequence_基于Mysql的Sequence实现

团队更换新框架。新的业务全部使用新的框架,甚至是新的数据库--Mysql。

这边之前一直是使用oracle,各种订单号、流水号、批次号啥的,都是直接使用oracle的sequence提供的数字序列号。现在数据库更换成Mysql了,显然以前的老方法不能适用了。

需要新写一个:

分布式场景使用

满足一定的并发要求

找了一些相关的资料,发现mysql这方面的实现,原理都是一条数据库记录,不断update它的值。然后大部分的实现方案,都用到了函数。

贴一下网上的代码:

基于mysql函数实现

表结构

CREATE TABLE `t_sequence` (

`sequence_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '序列名称' ,

`value` int(11) NULL DEFAULT NULL COMMENT '当前值' ,

PRIMARY KEY (`sequence_name`)

)

ENGINE=InnoDB

DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci

ROW_FORMAT=COMPACT

;

获取下一个值

CREATE DEFINER = `root`@`localhost` FUNCTION `nextval`(sequence_name varchar(64))

RETURNS int(11)

BEGIN

declare current integer;

set current = 0;

update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name;

select t.value into current from t_sequence t where t.sequence_name = sequence_name;

return current;

end;

并发场景有可能会出问题,虽然可以在业务层加锁,但分布式场景就无法保证了,然后效率应该也不会高。

自己实现一个,java版

原理:

读取一条记录,缓存一个数据段,如:0-100,将记录的当前值从0修改为100

数据库乐观锁更新,允许重试

读取数据从缓存中读取,用完再读取数据库

不废话,上代码:

基于java实现

表结构

每次update,都是将SEQ_VALUE设置为SEQ_VALUE+STEP

CREATE TABLE `t_pub_sequence` (

`SEQ_NAME` varchar(128) CHARACTER SET utf8 NOT NULL COMMENT '序列名称',

`SEQ_VALUE` bigint(20) NOT NULL COMMENT '目前序列值',

`MIN_VALUE` bigint(20) NOT NULL COMMENT '最小值',

`MAX_VALUE` bigint(20) NOT NULL COMMENT '最大值',

`STEP` bigint(20) NOT NULL COMMENT '每次取值的数量',

`TM_CREATE` datetime NOT NULL COMMENT '创建时间',

`TM_SMP` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',

PRIMARY KEY (`SEQ_NAME`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水号生成表';

sequence接口

/**

*

* @author coderzl

* @Title MysqlSequence

* @Description 基于mysql数据库实现的序列

* @date 2017/6/6 23:03

*/

public interface MysqlSequence {

/**

*

* 获取指定sequence的序列号

*

* @param seqName sequence名

* @return String 序列号

*/

public String nextVal(String seqName);

}

序列区间

用于本地缓存一段序列,从min到max区间

/**

*

*

* @author coderzl

* @Title SequenceRange

* @Description 序列区间,用于缓存序列

* @date 2017/6/6 22:58

*/

@Data

public class SequenceRange {

private final long min;

private final long max;

/** */

private final AtomicLong value;

/** 是否超限 */

private volatile boolean over = false;

/**

* 构造.

*

* @param min

* @param max

*/

public SequenceRange(long min, long max) {

this.min = min;

this.max = max;

this.value = new AtomicLong(min);

}

/**

*

Gets and increment

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值