Flask+MongoDB如何防止文档被多次更新?并发请求更新异常
解决Flask+Gunicorn+PyMongo并发更新的竞态问题
你的问题出在非原子操作上:先查询文档、再判断状态、最后执行更新,这三步在并发场景下会被多个请求同时触发。多个请求都会读到already_edited: False,随后各自执行更新,导致rate被多次累加。
要解决这个问题,必须把查询条件和更新操作合并成原子操作,让MongoDB在同一事务里完成条件校验与数据更新,彻底避免竞态。
修改后的代码如下:
@app.route('/test_update') def test_update(): # 将查询条件(_id=1 且 already_edited=False)与更新操作合并 result = db.collection.update_one( { '_id': 1, 'already_edited': False }, { '$inc': {'rate': 1}, '$set': {'already_edited': True} } ) # 根据更新是否成功返回对应结果 if result.modified_count > 0: return 'OK' else: return 'ERROR', 403
为什么这样有效?
MongoDB的update_one方法是原子性的:它会先匹配同时满足_id=1和already_edited=False的文档,只有匹配成功才会执行更新操作。即使有多个并发请求同时到达,MongoDB也会保证只有一个请求能成功修改文档,其他请求会因条件不匹配无法执行更新,modified_count会返回0。
这样就能确保文档只会被更新一次,rate最终只会变成1,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Mattew Silva
相关产品推荐
相关产品推荐

