代码环境
- 仓库:https://github.com/springvortex/spring-cloud-alibaba.git
- 分支:
release/v1.0.0- JDK:
21- Spring Boot:
4.1.1
商品购买接口确实要加分布式锁,但 Swagger 文档不应该告诉调用方“我们用的是 Redisson”。这次把描述里的实现名拿掉了:
@Operation(
summary = "购买商品",
description = "按商品维度使用分布式锁扣减库存并创建待支付订单"
)
调用方需要知道的契约是行为:购买会按商品维度串行化关键操作,避免并发扣错库存,并返回订单和剩余库存。至于锁来自 Redis、MySQL 还是 ZooKeeper,不影响请求参数、响应结构,也不改变失败语义。
服务层也已经依赖抽象:
GoodsPurchaseResponseDTO result = distributedLockFactory.getTemplate().execute(
PURCHASE_LOCK_KEY_PREFIX + goodsId, LOCK_WAIT, "当前购买人数过多,请稍后再试",
() -> {
GoodsPurchaseResponseDTO callbackResult;
try {
callbackResult = transactionTemplate.execute(status -> purchaseInTransaction(goodsId, request));
} catch (BusinessException e) {
throw e;
} catch (RuntimeException e) {
log.error("购买事务执行失败:goodsId={}, userId={}, quantity={}",
goodsId, request.getUserId(), request.getQuantity(), e);
throw e;
}
evictGoodsCache(goodsId);
return callbackResult;
});
默认实现由配置决定:
zjc:
distributed-lock:
provider: redis
如果哪天把 provider 换成 MySQL 或 ZooKeeper,购买接口的 HTTP 契约不应该变。文档若写死 Redisson,就会在实现切换时制造一次无意义的文档变更,甚至误导调用方把运维细节当成接口稳定性的一部分。
接口文档可以说明并发语义和可能的失败错误,例如“当前购买人数过多”,但不应该暴露供应商名、内部类名、表名或缓存 key 结构。那些属于实现和运维文档。
经验总结
API 文档写稳定契约,不写可替换实现。代码依赖 DistributedLockTemplate,文档描述“分布式锁”,两层边界保持一致。
评论
评论由 GitHub Discussions 承载,需要 GitHub 账号登录。