分布式系统下,数据库sequence 获取工具类

sequence  主键获取工具类,先打算如下实现:(基础要求:支持分布式请求下的序列唯一性)

最终表现形式,提供如下两个公共接口

1、入参是序列名称,返回是序列值,内部逻辑是向数据库查找下一个序列的值然后返回查询结果

SELECT ***.NEXTVAL SEQ FROM DUAL;

这个方法取到的序列严格遵循步长,每次请求都会建一次数据库连接走一次查询语句,相信Oracle的取序列api对并发请求的安全性支持,所以不需要做并发下的安全性处理(序列的严格连续性要看序列定义的时候是否启动缓冲区)

2、入参是序列名称,返回是序列值,内部逻辑是先查询此序列对应的序列信息

SELECT INCREMENT_BY, MAX_VALUE FROM USER_SEQUENCES WHERE SEQUENCE_NAME = '***';

将序列相关信息放入内存缓存,然后查询下一个序列值:

SELECT ***.NEXTVAL SEQ FROM DUAL;

将查到的序列值作为第一次查询的返回,并将查到的序列值放进内存缓存,在后续线程到来的时候,如果步长大于1,比如说是5,那么下4次请求会直接从内存计算取值并返回(这里要做并发安全处理)当第五次时,因为到了下一个步长,所以向数据库请求下一个值返回,并更新内存(这里要做并发安全处理)

这个方法取到的序列不遵循步长,而是每次+1,只有在步长规定的取值出才是向数据库查询拿到的值,其他的值是内存中计算出来。 这样的做法保证了数据库的异常断电仍然不会有重复序列的情况发生,但是服务器本身的进程重启有可能导致部分序列的不连续性

 

 

写了个测试类,连续起20个线程去请求序列,先看看表现     单服务请求,表现完美: 2018-10-16 20:11:47.726 INFO 14372 --- [ main] com.tang.billing.demo.SequenceUtilTest : ************===============************ 2018-10-16 20:11:47.841 INFO 14372 --- [ myThread8] com.tang.billing.demo.SequenceUtilTest : seq ret is 1thread number:8 2018-10-16 20:11:47.841 INFO 14372 --- [ myThread5] com.tang.billing.demo.SequenceUtilTest : seq ret is 3thread number:5 2018-10-16 20:11:47.841 INFO 14372 --- [ myThread9] com.tang.billing.demo.SequenceUtilTest : seq ret is 2thread number:9 2018-10-16 20:11:47.841 INFO 14372 --- [ myThread11] com.tang.billing.demo.SequenceUtilTest : seq ret is 4thread number:11 2018-10-16 20:11:47.841 INFO 14372 --- [ myThread7] com.tang.billing.demo.SequenceUtilTest : seq ret is 5thread number:7 2018-10-16 20:11:47.843 INFO 14372 --- [ myThread2] com.tang.billing.demo.SequenceUtilTest : seq ret is 6thread number:2 2018-10-16 2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clark Kent 2000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值