← 返回资讯

两名管理员先后保存渠道配置,怎样阻止旧页面覆盖新修改

2026-10-24

让保存语句同时匹配记录ID与读取时的版本号。第一份修改成功后版本递增,旧页面再次保存影响零行,服务端应返回冲突信息,要求用户比较新旧内容后重新提交。

复现最后写入覆盖

问题通常发生在两人都打开旧页面以后:甲先保存新路由,乙稍后提交旧页面里修改的超时,整个对象被写回,甲的路由随之消失。只按ID执行UPDATE无法识别乙的编辑基础已经过期,页面有没有显示保存成功也不能说明并发修改得到保护。

定义实体版本与提交条件

样本把版本固定为7,两份编辑都基于这一版本。第一份条件更新影响一行并升到8;第二份仍要求version=7,所以影响零行。最终正文保持first、版本保持8。附件中的409只是演示接口如何表达这种冲突,数据库本身不会替管理API自动生成HTTP响应。

保存接口可以把UPDATE影响行数作为数据库竞争结果,再结合授权范围判断返回内容。版本号应随同需要保护的配置字段一起递增,不能只在页面刷新时改。若配置允许删除后重建,还要考虑新对象是否可能复用旧ID与旧版本,避免旧编辑误匹配到另一代记录。

核心表达式(完整建表与输入见附件):

UPDATE channels SET body=?, version=version+1
WHERE id=? AND version=?;

说明版本锁不涵盖跨实体事务

零行还可能来自记录已删除或授权条件不满足,接口不要把所有零行都公开成“版本冲突”,以免泄露别的租户记录。真正的合并应比较字段与业务约束;无条件拉取最新版本再自动重试旧整对象,等于绕过了原本想保护的更新边界。

适用范围:只演示数据库条件更新;HTTP409是样例管理接口协议,不冒充现成产品原生行为。

配套样本与复核入口

  • run.py:独立运行程序,包含合成输入、操作和正反例断言。
  • case.json:输入说明、预期任务与适用范围,便于保存和交接。
  • observed.json:本次实际执行输出;临时路径、进程号和计时可能随运行变化。

run.py会顺序提交两份基于版本7的编辑。first_rows应为1,stale_rows应为0,final应保留first与8。可以把第二份编辑的正文改成其他字符串,结果仍不能覆盖第一份。接入真实管理接口时,建议将记录ID、原版本与冲突提示一起记录,方便用户知道需要重新加载哪一份内容,而不是仅弹一个无法理解的失败。

Python3.8以上及标准库;使用Python自带SQLite。程序不读取现有网关数据库,全部样本写入内存或新建临时目录,执行完自动清理;没有任何模型API调用。

python -B run.py

阅读输出时,先按case.json中的任务逐项核对网关配置乐观锁版本冲突,再与observed.json比较。非零退出表示依赖或断言需要处理,应保留实际错误。

一手依据1(UPDATE用WHERE限定修改行;版本条件和冲突响应是本文应用协议。);一手依据2(占位符绑定参数;rowcount、连接超时及progress_handler等接口按相应小节使用。)。

继续阅读:渠道配置改成功却没留下审计记录,怎样把两次写入放进同一事务;两个网关任务同时累计用量为何少一笔,怎样用数据库原子累加替代先读后写;限流规则热更新时,怎样避免同一请求混读两个配置版本。

加微信,把这一页发到你手机上

扫码加站长企业微信,会自动把这一页的链接发给你。模型接入、token 计费上有问题,也可以直接问。

去留微信

不想自己搭网关、自己维护渠道?

力达云是托管的 OpenAI / Anthropic 双格式端点,一期提供 DeepSeek,注册送 ¥5 额度。

去试用

这个页面有问题?

提交时会附带当前页面地址和浏览器信息,帮助我们定位问题。不填联系方式即为匿名。