用版本号处理并发更新,避免旧请求覆盖新状态)
文章目录引言:没有数据竞争,为什么还会改错?一、本篇学习目标与准备二、锁和版本号,分别解决什么问题?1. Mutex 保护正在发生的内存操作2. 版本号判断读取之后有没有发生修改3. 两个页面的请求会怎样变化?三、先把版本规则约定清楚1. 什么时候增加版本?2. 旧版本碰巧与当前状态相同,能否直接成功?3. 它和幂等性是什么关系?四、让版本条件贯穿 Handler、Service 和 Store1. 修改存储接口2. Handler 为什么继续使用指针?3. 用可识别错误区分冲突五、内存版本:比较与修改必须放在同一个锁里六、SQLite 版本:把比较条件写进 UPDATE1. 为什么“先 SELECT,再 UPDATE”不够?2. 没返回行,不一定代表任务不存在3. 为什么限制一个连接仍然需要版本号?七、已有数据库怎么增加 version?1. 只改 CREATE TABLE 不会修改旧表2. 重启时不能把版本重新设为13. 本篇迁移的适用范围八、实际走一遍:成功、冲突、刷新、再修改1. 启动服务2. 创建任务3. 页面A设置完成4. 模拟页面B提交旧版本5. 读取最新任务后,明确要求恢复未完成九、前端收到409,怎样处理才有意义?1. 保留读取时拿到的版本2. 为什么不能自动刷新版本后再次写入?3. 还需要防重复点击吗?十、测试要检查返回值,也要检查没有发生什么1. 内存与 SQLite 共用版本行为测试2. 让多个请求真正竞争同一版本3. HTTP 与迁移测试4. 本次实际验证范围十一、实战练习与下一步练习1:增加标题编辑练习2:测试状态变回原值练习3:设计冲突提示参考资料✍创作者:全栈弄潮儿🏡 个人主页:全栈弄潮儿的个人主页🏙️ 个人社区,欢迎你的加入:全栈开发社区📙 专栏:Go零基础实战引言:没有数据竞争,为什么还会改错?第21篇,我们给内存 map 加了锁;第22篇把任务保存到 SQLite;第23篇又增加了分页和状态筛选。看起来,任务已经能安全地创建、查询和修改。但假设你打开两个页面,它们都显示同一条任务未完成:页面A把任务设为已完成,保存成功。页面B还停留在旧画面,稍后保存表单,把里面的completed=false发给服务端。服务端照单全收,任务又变回未完成。两次请求即使严格