幂等一二三

最近开发提现相关的功能,需要考虑幂等性。向社区取了点经,把自己的实现方法写下来。不会高谈阔论什么是幂等,幂等种类等高深的问题。只是简单的写下步骤,题目来源于此。

为什么需要幂等

分布式环境里面,网络不可控,计算机不可控,都有失败风险。先给定两个角色,server,client,client是请求发起者,server是请求接收者并处理业务逻辑。第一次请求任何地方失败了就直接告诉客户处理失败,这没有问题,但是可用性不好,体验差。有什么办法提高?答案是有限次的重试,比如重试三次,第一次失败,还有第二次或者第三次机会。

问题来了,server接受到的请求可能是0个,1个,2个,或者3个。server收到3个重复的提现请求,当然只能最多真的提现一次。幂等解决的就是这个问题,最多处理一次,At Most Once。没有重复发请求的场景,不要考虑幂等问题。另外请求发出,server端只是查询,没有副作用,说明调用安全,也无需考虑幂等。

幂等解决思路

提供请求的身份证号码,或者叫请求的ID,不同的请求不同的ID,重复的请求共享相同的ID。做的第一件事情是要区别请求相同还是不同。区分开了请求的异同,接下来就是实施,实施的思路很简单,根据请求ID查看请求是否处理成功,成功就跳出处理流程,告知已处理,不成功就继续处理。

具体步骤

  1. 提供ID生成服务。client可以调用该服务,获取新的ID。
    这一步可以跳过,client自己生成符合规范的唯一ID可行。

    String getTransactionId()
    
  2. client端调用携带请求ID。

    String transactionId = transactionService.getTransactionId();
    
    while(int i< 3){
        Response response = invokeServer(transactionId, request);
        if(response.isSuccess()){
            break;
        }
        i++;
     }
    
  3. server端实现
    提现涉及金钱,比较敏感,数据库事务必不可少。所以server端的逻辑依赖数据库事务。

3.1 建ID池,用table表示

CREATE TABLE `transaction` (
    `transaction_id` VARCHAR(64) NOT NULL COMMENT '事务ID',
    PRIMARY KEY (`transaction_id`)
)

3.2 事务保证

@Transactional
public class BusinessServiceImpl inplements BusinessService{
    @Override
    public void doSomething(String transactionId, Request request){
        // 向transaction表计入transactionId
        transactionDao.insert(new Transaction(transactionId));
        // 处理具体的业务逻辑
        doBussiness(request);
    }
}
  • transaction表的插入与业务处理,放到同一个事务,要么都成功,要么都失败。
  • 相同的transactionId,由于transaction用transactionId作为主键,所以transaction最多有一个插入成功。
    所以业务处理也最多只有一次成功,搞定。

其它

谁发起请求,谁负责transactionId。
能够接受成功处理0次,但是不接受处理大于1次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值