java幂等的实现方案_java的幂等性

幂等性应用在软件系统中,它简单定义为:某个函数或者某个接口使用相同参数调用一次或者无限次,其造成的后果是一样的,在实际应用中一般针对于接口进行幂等性设计

幂等性一般应用于协议设计,TCP协议支持幂等吗?答案是肯定的,在网络不稳定时,操作系统可以肆无忌惮的重发TCP报文片段。TCP协议能够保证幂等的核心在于sequence number字段,

一个序列号的在较长的一段时间内均不会出现重复。对于应用层的协议设计,原理和TCP是类似的,我们需要一个不重复的序列号。再简单一点说,在一个业务流程的处理中,

我们需要一个不重复的业务流水号,以保证幂等性。

一::token机制,防止页面重复提交

业务要求:

页面的数据只能被点击提交一次

发生原因:

由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交

解决办法:

集群环境:采用token加redis(redis单线程的,处理需要排队)

单JVM环境:采用token加redis或token加jvm内存

处理流程:

1. 数据提交前要向服务的申请token,token放到redis或jvm内存,token有效时间

2. 提交后后台校验token,同时删除token,生成新的token返回

token特点:

要申请,一次有效性,可以限流

注意:redis要用删除操作来判断token,删除成功代表token校验通过,如果用select+delete来校验token,存在并发问题,不建议使用

二.唯一索引,防止新增脏数据

比如:支付宝的资金账户,支付宝也有用户账户,每个用户只能有一个资金账户,怎么防止给用户创建资金账户多个,那么给资金账户表中的用户ID加唯一索引,所以一个用户新增成功一个资金账户记录

三. 悲观锁

获取数据的时候加锁获取

select * from table_xxx where id='xxx' for update;

注意:id字段一定是主键或者唯一索引,不然是锁表,会死人的

悲观锁使用时一般伴随事务一起使用,数据锁定时间可能会很长,根据实际情况选用

四. 乐观锁

乐观锁只是在更新数据那一刻锁表,其他时间不锁表,所以相对于悲观锁,效率更高。

乐观锁的实现方式多种多样可以通过version或者其他状态条件:

通过版本号实现

update table_xxx set name=#name#,version=version+1 where version=#version#

五. 状态机幂等

在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机(状态变更图),就是业务单据上面有个状态,

状态在不同的情况下会发生变更,一般情况下存在有限状态机,这时候,如果状态机已经处于下一个状态,

这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等

10. 对外提供接口的api如何保证幂等

如银联提供的付款接口:需要接入商户提交付款请求时附带:source来源,seq序列号

source+seq在数据库里面做唯一索引,防止多次付款,(并发时,只能处理一个请求)

重点:

对外提供接口为了支持幂等调用,接口有两个字段必须传,一个是来源source,一个是来源方序列号seq,

这个两个字段在提供方系统里面做联合唯一索引,这样当第三方调用时,先在本方系统里面查询一下,是否已经处理过,返回相应处理结果;没有处理过,进行相应处理,返回结果。

注意,为了幂等友好,一定要先查询一下,是否处理过该笔业务,不查询直接插入业务系统,会报错,但实际已经处理了。

引用博文 :幂等性实现方案

RocketMq解决消息顺序和重复,Mysql与Java中的乐观锁悲观锁

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值