← 返回并发与锁

🔁 幂等性

重复执行结果不变 —— 用户连点两次只扣一次钱

❌ 不幂等(扣两次)

用户点支付 → 网络超时 → 用户再点 → 扣了两次钱

✅ 幂等(只扣一次)

用户点支付 → 带唯一 requestId → 再点带同样的 requestId → 第二次发现已处理,直接返回成功

// ✅ 方案1:唯一索引(数据库层,最可靠) try { orderDao.insert(order); // requestId 建唯一索引 payDao.deduct(money); } catch (DuplicateKeyException e) { return "已支付"; // requestId 已存在,已处理过 } // ✅ 方案2:Redis 标记(应用层,快) boolean isNew = redis.setIfAbsent("pay:"+requestId, "1", 24, HOURS); if (!isNew) return "已支付"; // key 已存在=已处理 // ✅ 方案3:Token 机制(前端先获取一次性token) // 前端先 GET /token → 提交时带token → 后端 redis.del(token) → 返回1才处理 // ✅ 方案4:状态机(业务层) int n = orderDao.updateStatus(id, "UNPAID", "PAID"); // WHERE status='UNPAID' → 只能改一次,再调返回0 if (n == 0) return "已支付";
天然幂等:GET、DELETE、PUT(指定ID全量更新)。非幂等:POST(新增)。写接口(资金/订单/支付)必须强制幂等!
四种方案:唯一索引(DB层,最可靠);② Redis setnx(应用层,快);③ Token机制(前端配合);④ 状态机(有状态流转)。核心都是用唯一标识判断"是否处理过"。
并发与锁 · 幂等性 · 全栈资料库