幂等和防重

每年的双十一,618,电商系统都会面临这超高的流量,如果一个订单被反复提交,那电商系统如何保证这个订单之后执行一次减库存,扣款的操作?
这里就引入两个概念,幂等和防重。
幂等(Idempotence)和防重(Idempotency in data handling or Anti-replay)是两个在计算机科学和数据处理中经常遇到的概念,尤其在分布式系统、网络通信和数据库操作中非常重要。
今天来聊聊二者的区别在哪里
1. 幂等 (Idempotence)
1.1 定义
一个操作是幂等的,意味着无论这个操作执行多少次,结果都是一样的。换句话说,执行一次和多次对系统的影响是相同的。
1.2 应用场景

网络通信:避免网络不稳定导致的重复请求改变结果,如HTTP的GET请求。
分布式系统:保持系统状态一致,特别是在组件间通信不确定的情况下。
数据库事务:确保重复执行的SQL语句不改变数据库状态。
支付和金融交易:防止因重复操作导致的财务错误,如重复支付处理。
订单处理系统:避免重复订单或不一致的订单状态。
任务或作业调度:确保重复执行任务不产生副作用。

1.3 实现思路

使用唯一事务标识符。
状态检查,避免重复执行相同状态的操作。
乐观锁或其他并发控制机制。

示例代码

点击查看代码
public class BankAccount {
    private double balance;

    public BankAccount(double balance) {
        this.balance = balance;
    }

    // 幂等的存款方法
    public void deposit(double amount, String transactionId) {
        if (!isTransactionProcessed(transactionId)) {
            balance += amount;
            markTransactionAsProcessed(transactionId);
        }
    }

    private boolean isTransactionProcessed(String transactionId) {
        // 实现检查逻辑
        return false;
    }

    private void markTransactionAsProcessed(String transactionId) {
        // 实现标记逻辑
    }
}

2. 防重 (Anti-replay or Idempotency in Data Handling)

2.1 定义
防重处理是确保不会重复处理相同的数据或请求的方法,用于避免由于重复执行相同操作而产生的数据错误或资源浪费。

2.2 应用场景
网络安全:防止重放攻击,保护API免受重复请求攻击。
金融服务和支付系统:防止重复交易和错误的资金扣除。
电子商务:避免重复下单和库存数据不一致。
消息队列和分布式系统:确保消息不被重复处理,防止数据同步错误。
Web服务和API:避免重复表单提交和REST API的重复请求。
身份验证和授权:管理Session和防止重复使用认证信息。

2.3 实现思路
为每个请求或操作分配唯一标识符。
跟踪和存储请求的状态,避免重复处理。
结合速率限制、请求去重和缓存机制。

示例代码

点击查看代码
import java.util.HashSet;
import java.util.Set;

public class RequestHandler {
    private Set<String> processedRequests = new HashSet<>();

    public void handleRequest(String requestId) {
        if (!processedRequests.contains(requestId)) {
            process(requestId);
            processedRequests.add(requestId);
        } else {
            // 已处理的请求
        }
    }

    private void process(String requestId) {
        // 实现请求处理逻辑
    }
}

3. 对比分析

posted @ 2024-02-05 14:52  恨铁不成钢2  阅读(24)  评论(0)    收藏  举报