基于Mysql Sequence组件(mysql版)
背景说明: 项目过程中经常使用到SEQ自增的场景,之前很多情况使用 “雪花算法”,此方案的弊端在于 SEQ随机,无规律可循。
解决方案: 通过DB的方式自增数据,提供”SEQ唯一码“、”起始基数值“、”最大基数值“、”当前唯一码值“、”自增累加值“等通用的方案,解决唯一SEQ且不重复问题。
1、该方案只限于 数字类型(number类型)不支持含有字母的场景。
2、该方案 已通过 多线程验证,集群部署不会重复取值(模拟流程平台EOS_UNIONE_TABLE方案)
相关Mysql脚本
- 1、创建唯一SEQ的公共表:
-- 创建SEQ的包,如果已创建,切勿删除,否则会存在存量数据
-- ----------------------------
CREATE TABLE `g_sys_sequence` (
`seq_name` varchar(50) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL COMMENT 'SEQ唯一码,获取SEQ用',
`min_value` int(11) NOT NULL COMMENT '起始基数值SEQ',
`max_value` int(11) NOT NULL COMMENT '最大基数值SEQ',
`current_value` int(11) NOT NULL COMMENT '当前SEQ的值',
`increment_value` int(11) NOT NULL DEFAULT 1 COMMENT '自增步长',
PRIMARY KEY (`seq_name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- 插入实例数据(此数据为生成机器人制单的ID)
-- ----------------------------
INSERT INTO `g_sys_sequence` VALUES ('robot_seq_subid', 100000000, 999999999, 100000000, 1);
- 2、创建MYSQL函数(因不支持SEQ,使用函数替代):
-- 创建SEQ的函数
-- ----------------------------
DELIMITER $$
CREATE FUNCTION `g_sys_seq_nextval`(name varchar(50)) RETURNS int(11)
begin
declare _cur int;
declare _maxvalue int; -- 接收最大值
declare _increment int; -- 接收增长步数
set _increment = (select increment_value from g_sys_sequence where seq_name = name);
set _maxvalue = (select max_value from g_sys_sequence where seq_name = name);
set _cur = (select current_value from g_sys_sequence where seq_name = name);
update g_sys_sequence -- 更新当前值
set current_value = _cur + increment_value
where seq_name = name ;
if(_cur + _increment >= _maxvalue) then -- 判断是都达到最大值
update g_sys_sequence
set current_value = min_value
where seq_name = name ;
end if;
return _cur;
end$$
DELIMITER ;
- 3、执行获取SEQ的函数(验证是否能够获取成功)
-- 创建SEQ的函数(参数为:步骤1中插入的数据 SEQ唯一值),此处的SQL需要在java的mapper中使用
-- ----------------------------
select g_sys_seq_nextval('robot_seq_subid') as robot_seq_subid;
- 4、JAVA代码编写获取SEQ的方法
-- 创建SEQ的函数(参数为:步骤1中插入的数据 SEQ唯一值),此处的SQL需要在java的mapper中使用
-- ----------------------------
select g_sys_seq_nextval('robot_seq_subid') as robot_seq_subid;
- 5、java中 XXXMapper.java 查询代码:
/**
* 获取DB中的唯一码值SEQ
* @return 自增的下一个SEQ值
*/
@Select("select g_sys_seq_nextval('robot_seq_subid') as robot_seq_subid")
int robotSeqSubid();
- 6、java中 XXXServiceImpl.java 调用代码:
public Result<?> resetPassword(String username, String oldpassword, String newpassword, String confirmpassword) {
/**
* 获取唯一的SEQID
*/
int uuid = userMapper.getRobotSeqSubid();
System.out.println(uuid);
}