一:概述
很多业务场景都需要获取不重复的业务流水号,当微服务项目或服务多节点部署时,获取流水号场景使用分布式锁性能低下,可以基于数据库行锁实现获取不重复流水号。
二:创建流水号数据库
sql
CREATE TABLE `serial` (
`id` varchar(32) NOT NULL COMMENT '唯一标识',
`prefix` varchar(32) DEFAULT NULL COMMENT '流水前缀',
`num` int(11) DEFAULT NULL COMMENT '流水序号',
PRIMARY KEY (`id`),
UNIQUE KEY `serial_prefix_IDX` (`prefix`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水号';
三:获取流水工具
3.1:创建mapper方法及对应xml文件
xml
## mapper文件创建两个方法
/**
* 根据前缀获取流水号
* @param prefix
* @return
*/
Serial getByPrefix(@Param("prefix")String prefix);
/**
* 更新流水号
* @return
*/
Integer updSerial(@Param("id")String id,@Param("num")Integer num);
## 对应 xml文件方法
<select id="getByPrefix" resultType="。。。Serial">
select * from serial sde where prefix = #{prefix}
</select>
<update id="updSerial">
update serial set num=#{num}+1 where id=#{id} and num =#{num}
</update>
3.2:获取流水号方法
java
@Resource
private SerialMapper mapper;
@Override
public String getNum(String prefix) {
while (true){
Serial num = mapper.getByPrefix(prefix);
if(num==null){
this.insert(new Serial(prefix,1));
return String.format("%05d",1);
}else {
if(mapper.updSerial(num.getId(),num.getNum())>0){
return String.format("%05d",num.getNum()+1);
}
}
}
}