MongoDB开启retryWrites时使用$inc运算符是否存在风险?
MongoDB retryWrites 配置下 $inc 运算符异常问题说明
你遇到的整数字段偶发异常偏高的问题,本质是retryWrites机制和非幂等运算符的特性冲突导致,并非$inc本身存在安全漏洞。
根本原因
MongoDB 可重试写入的逻辑是:当驱动未收到写入请求的明确成功/失败回执时(比如主节点切换、网络临时中断等故障转移场景),会自动重发完全相同的写入请求。
$inc属于非幂等运算符,相同的请求执行多次会产生累加效果:比如原字段值为5,执行{$inc: {view_count: 1}}一次得到6,重复执行就会得到7,完全符合偶发数值偏高的特征。
推荐最佳实践
- 不需要完全规避
$inc等累加类运算符:可重试写入仅会在故障转移的几秒窗口期内重试未确认的写入,正常运行时不会触发重复执行,大多数对精度要求不高的统计类场景(比如点赞数、浏览量统计)完全可以正常使用。 - 对数值精度要求极高、不允许出现任何偏差的业务场景,推荐做幂等改造,两种常用方案:
- 改用乐观锁更新:更新时携带版本号校验条件,只有版本号匹配时才执行更新,示例语句:
即使请求被重试,版本号不匹配就不会触发二次更新,完全避免重复累加。db.order.updateOne( {_id: "xxx", version: 3}, {$set: {stock: 10, version: 4}} )
2. 针对特定的非幂等写入请求单独关闭retryWrites,不要全局关闭该配置,否则会导致故障转移场景下大量写入直接失败,严重影响业务可用性。
内容的提问来源于stack exchange,提问作者Dom Ramirez
相关产品推荐
相关产品推荐

