Admin:迁移 Repository SQL 与并发事务到 MySQL 8 #79

Closed
opened 2026-08-10 01:09:14 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:重构
  • 父级大工单:#76
  • 所属 MVP / 版本:#77
  • 阶段:2 业务数据访问

要解决什么

Repository 当前包含 SQLite 专用 upsert、JSON、日期、部分索引和事务锁语义。直接换驱动会在启动、查询或并发领取时失败。

做什么 / 不做什么

  • 做:将全部生产 repository SQL 改为 MySQL 8 语义;实现行锁/条件更新保护;把测试迁移到真实隔离 MySQL 8.4。
  • 不做:不迁移生产数据、不部署线上、不改变 Client 四接口字段和状态。

怎么做

  • 将 ON CONFLICT、julianday、SQLite JSON 函数和大小写比较改为 MySQL 8 等价实现。
  • 用生成列/唯一索引表达“一个客户端只有一个当前归属”,不依赖部分唯一索引。
  • 任务领取使用事务 + SELECT ... FOR UPDATE SKIP LOCKED 或等价条件更新,保持指定/无主领取规则。
  • 首次管理员初始化、批量建任务、顺运宝同步、幂等提交均按 InnoDB 并发语义复测。
  • 测试每次创建独立数据库或独立 schema,结束后安全清理;禁止连接生产库运行破坏性测试。

预计修改:admin/repository/*.go、相关 service 和全量 *_test.go。

验收标准

  • 全部 repository 生产 SQL 可在 MySQL 8.4 执行,不再依赖 SQLite PRAGMA/方言。
  • 两个客户端并发领取同一任务时只有一个成功。
  • 指定任务、无主任务、迟到结果、重派结果和幂等冲突契约保持不变。
  • 用户名唯一性、当前客户端归属唯一性和软删除规则保持一致。
  • PDD JSON 规格数、筛选、分页和状态统计结果与原 SQLite 一致。
  • 全量 Go 1.23 测试在隔离 MySQL 8.4 测试库通过。

怎么验证

运行全量 Go 1.23 build/test/vet;对 MySQL 8.4 执行并发领取、幂等、登录、顺运宝和页面集成测试。

风险和回退

事务和排序差异可能造成重复领取或查漏数据。生产尚未切换,失败时回退代码并继续使用原 SQLite。

实施记录

  • 已将生产启动入口切换到 MySQL 8 环境变量配置。
  • Repository upsert、JSON、LIKE、分页、在线统计和保留字已迁移为 MySQL 8 语义。
  • 任务领取使用 InnoDB FOR UPDATE SKIP LOCKED;领取状态与历史同事务提交。
  • 首位管理员初始化使用哨兵行锁;客户端转交锁定客户端行。
  • 并发幂等冲突由唯一键选出赢家,失败事务回滚后复用赢家响应。
  • 实现提交:13cfced。

测试结果

  • GOTOOLCHAIN=local go test ./... -count=1 -timeout=20m:通过(真实隔离 MySQL 8.4;service 929.519s)。
  • GOTOOLCHAIN=local go vet ./...:通过。
  • git diff --check:通过。
  • 未连接或修改线上生产 MySQL 数据库。
## 基本信息 - 类型:重构 - 父级大工单:#76 - 所属 MVP / 版本:#77 - 阶段:2 业务数据访问 ## 要解决什么 Repository 当前包含 SQLite 专用 upsert、JSON、日期、部分索引和事务锁语义。直接换驱动会在启动、查询或并发领取时失败。 ## 做什么 / 不做什么 - 做:将全部生产 repository SQL 改为 MySQL 8 语义;实现行锁/条件更新保护;把测试迁移到真实隔离 MySQL 8.4。 - 不做:不迁移生产数据、不部署线上、不改变 Client 四接口字段和状态。 ## 怎么做 - 将 `ON CONFLICT`、`julianday`、SQLite JSON 函数和大小写比较改为 MySQL 8 等价实现。 - 用生成列/唯一索引表达“一个客户端只有一个当前归属”,不依赖部分唯一索引。 - 任务领取使用事务 + `SELECT ... FOR UPDATE SKIP LOCKED` 或等价条件更新,保持指定/无主领取规则。 - 首次管理员初始化、批量建任务、顺运宝同步、幂等提交均按 InnoDB 并发语义复测。 - 测试每次创建独立数据库或独立 schema,结束后安全清理;禁止连接生产库运行破坏性测试。 预计修改:`admin/repository/*.go`、相关 service 和全量 `*_test.go`。 ## 验收标准 - [x] 全部 repository 生产 SQL 可在 MySQL 8.4 执行,不再依赖 SQLite PRAGMA/方言。 - [x] 两个客户端并发领取同一任务时只有一个成功。 - [x] 指定任务、无主任务、迟到结果、重派结果和幂等冲突契约保持不变。 - [x] 用户名唯一性、当前客户端归属唯一性和软删除规则保持一致。 - [x] PDD JSON 规格数、筛选、分页和状态统计结果与原 SQLite 一致。 - [x] 全量 Go 1.23 测试在隔离 MySQL 8.4 测试库通过。 ## 怎么验证 运行全量 Go 1.23 build/test/vet;对 MySQL 8.4 执行并发领取、幂等、登录、顺运宝和页面集成测试。 ## 风险和回退 事务和排序差异可能造成重复领取或查漏数据。生产尚未切换,失败时回退代码并继续使用原 SQLite。 ## 实施记录 - 已将生产启动入口切换到 MySQL 8 环境变量配置。 - Repository upsert、JSON、LIKE、分页、在线统计和保留字已迁移为 MySQL 8 语义。 - 任务领取使用 InnoDB FOR UPDATE SKIP LOCKED;领取状态与历史同事务提交。 - 首位管理员初始化使用哨兵行锁;客户端转交锁定客户端行。 - 并发幂等冲突由唯一键选出赢家,失败事务回滚后复用赢家响应。 - 实现提交:13cfced。 ## 测试结果 - GOTOOLCHAIN=local go test ./... -count=1 -timeout=20m:通过(真实隔离 MySQL 8.4;service 929.519s)。 - GOTOOLCHAIN=local go vet ./...:通过。 - git diff --check:通过。 - 未连接或修改线上生产 MySQL 数据库。
Author
Owner

实现和真实 MySQL 8.4 全量回归已完成,提交 13cfced。工单进入待验收;生产数据迁移与线上部署分别由 #80、#81 跟踪。

实现和真实 MySQL 8.4 全量回归已完成,提交 `13cfced`。工单进入待验收;生产数据迁移与线上部署分别由 #80、#81 跟踪。
Author
Owner

本地归档已提交:86b9e69,文档 docs/task/79-mysql8-repository迁移.md。工单保持开启,等待用户验收。

本地归档已提交:`86b9e69`,文档 `docs/task/79-mysql8-repository迁移.md`。工单保持开启,等待用户验收。
Author
Owner

用户已明确验收通过。验收清单已回填,本工单关闭。

用户已明确验收通过。验收清单已回填,本工单关闭。
ila closed this issue 2026-08-10 23:23:02 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#79