首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >多端学习进度同步不回退:版本号合并与断点续学的工程实现

多端学习进度同步不回退:版本号合并与断点续学的工程实现

原创
作者头像
用户5598620
发布2026-09-19 09:00:49
发布2026-09-19 09:00:49
440
举报

学员在手机上看了一半的课,换平板想接着看,最烦遇到两种情况:进度没同步、或者同步了却倒退了几分钟。这类问题的根因不是"没存进度",而是多端并发上报时的覆盖与乱序。本文讲多端学习进度同步的方案:上报幂等、版本号合并、防回退与断点续学,附可直接落地的表结构与接口设计。

一、学员在手机、平板、网页端的学习进度怎么保持一致

先定义进度模型。一条学习进度 = 学员 + 课程 + 课时 + 播放位置,多端同步的目标是:任何一端读到的都是"最新且有效"的进度。最朴素的实现是只存一个 position 字段,谁后上报谁覆盖——这恰好是回退的根源:

手机端看到 12:30 上报 12:35 → 平板端因弱网延迟 5 分钟,此时才上报 12:28 → 服务端按时间戳或简单覆盖,进度被改回 12:28

要避免覆盖,进度表必须带上版本号,把"覆盖"变成"合并":

代码语言:sql
复制
CREATE TABLE study_progress (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,
  course_id BIGINT NOT NULL,
  lesson_id BIGINT NOT NULL,
  position_sec INT NOT NULL DEFAULT 0,
  version BIGINT NOT NULL DEFAULT 0,
  updated_at DATETIME NOT NULL,
  UNIQUE KEY uk_progress (user_id, course_id, lesson_id)
);

version 是单调递增的版本号,服务端生成,客户端不参与竞争。同一课时的进度更新走条件写,旧版本自然失效:

代码语言:sql
复制
UPDATE study_progress
SET position_sec = #{position},
    version = version + 1,
    updated_at = NOW()
WHERE user_id = #{userId}
  AND course_id = #{courseId}
  AND lesson_id = #{lessonId}
  AND version = #{clientVersion};

影响行数为 0 说明客户端版本已过期,直接丢弃,让客户端拉取最新进度对齐。

一次完整的上报与合并时序可以收敛成下面的状态流转:

播放中(本地节流5s) → 组装上报(report_no=设备序号自增) → 判重(报告表唯一键) → 已存在:幂等成功; 不存在:更新进度(版本条件+前进判定) → 更新成功:返回最新进度; 更新失败(版本过期):拉取服务端进度本地对齐 → 继续播放

把"判重"和"合并"放在同一事务里,可以避免"报告已记录但进度未更新"的中间态:先插报告表,成功后再更新进度,两步在同一事务提交;更新失败则回滚报告记录,让客户端重试。

二、进度上报怎么保证不丢、不重复

客户端会高频上报(播放中每 5 秒一次),网络重试又可能重复投递。上报接口要做幂等:用"设备 + 上报序号"做唯一键,同一批数据重复到达只生效一次:

代码语言:sql
复制
CREATE TABLE progress_report_log (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  user_id BIGINT NOT NULL,
  device_id VARCHAR(64) NOT NULL,
  report_no VARCHAR(64) NOT NULL,
  payload_json TEXT NOT NULL,
  created_at DATETIME NOT NULL,
  UNIQUE KEY uk_report (user_id, device_id, report_no)
);

写入先判重:report_no 已存在直接返回成功(幂等成功),不存在才插入并触发进度更新。这样客户端超时重试、连点、断线重连都不会造成重复处理。

三、多个设备同时看,进度冲突怎么合并

同一学员手机、平板同时播放同一课时时,两端各自上报,谁才是"正确"进度?合并规则要明确:只允许前进,不允许回退,且以版本号裁决冲突。

服务端合并规则: 1. 上报的 position_sec 必须大于当前已存值,否则视为过期上报,丢弃; 2. 版本号落后于服务端的上报一律拒绝; 3. 前进量异常大(如一次前进超过 1 小时且不是跳播)时标记待人工确认,不直接采纳。

把规则落到更新语句里:

代码语言:sql
复制
UPDATE study_progress
SET position_sec = #{position},
    version = version + 1
WHERE user_id = #{userId}
  AND course_id = #{courseId}
  AND lesson_id = #{lessonId}
  AND version = #{clientVersion}
  AND position_sec > (
    SELECT position_sec FROM study_progress
    WHERE user_id = #{userId} AND course_id = #{courseId} AND lesson_id = #{lessonId}
  );

MySQL 不允许在 UPDATE 的同一张表上子查询,实际实现可先 SELECT 当前值再在应用层判断,或拆成两步事务;关键是把"前进判定 + 版本校验"放进同一次更新,而不是先查后改。

四、进度读取怎么做才不拖垮服务

进度的读取频率远高于写入:每节课进入时拉取、每 5 秒心跳回显。读接口要控制回源。标准做法是缓存优先 + 写后失效:

代码语言:bash
复制
# 读取:先查缓存,命中直接返回;未命中回源数据库并回填
GET study_progress:{userId}:{courseId}:{lessonId}   # Redis
# 写入:进度合并成功后,主动删除对应缓存,下次读取重新回填
DEL study_progress:{userId}:{courseId}:{lessonId}

缓存不用存太多——每课一条小记录,TTL 设 1 小时足够。删除而不是直接更新缓存,可以避免缓存与数据库的短暂不一致(删除后读取重建,天然拿最新值)。对播放器类高并发读的场景,缓存命中率能到 90% 以上,主库只承接合并写入。

五、断点续学的位置怎么防回退

断点续学的"续"也要做合法性校验:播放位置不能为负、不能超过课时总时长、不能明显小于上次已确认的位置。课时总时长在课程元数据里维护,续学接口返回时做一次钳制:

续学返回 position = min(max(0, 最新合法位置), lesson_duration)

同时把"已学完"状态单独标记,避免学员看完一节课后,另一个设备又把它拉回未完成状态——完成态只允许正向推进,不允许被低版本覆盖。

踩坑清单

  • 只存单值不存版本号,旧设备一上报就把新进度覆盖回退;
  • 用客户端时间戳当版本号,设备时钟不准直接乱序;
  • 上报接口不做幂等,网络重试造成重复写、重复统计;
  • 高频进度直接写 MySQL 主库,播放大户打爆数据库;
  • 断点续学不校验位置合法性,负值、超时长、跳播数据进库;
  • 完成状态和播放位置混在一个字段,看完又被拉回未完成;
  • 读接口每次都回源数据库,播放高峰把主库拖垮。

工程落地建议

通用做法是"幂等上报 + 版本号合并 + 只进不退 + 异步落库"四件套:上报写 Redis 暂存并做去重,定时任务批量落库;进度读取走缓存,命中失败再回源数据库。账号体系打通后,手机、平板、网页天然共享同一份进度。方案不依赖特定中间件,Redis 只做暂存与加速,数据最终落在 MySQL,任何规模的在线课程系统都可按此演进。

上线复盘清单

  • 进度表是否带版本号,更新是否带版本条件?
  • 上报接口是否用"设备 + 序号"做幂等?
  • 是否实现只前进不回退的合并规则?
  • 断点续学是否校验位置合法区间?
  • 高频上报是否走缓存暂存 + 异步落库?
  • 完成状态是否独立标记、不可被低版本覆盖?

常见问题

Q:在线课程学习进度在多端怎么保持同步不丢?

A:以"学员 + 课程 + 课时"为维度存一份带版本号的进度,客户端上报做幂等去重,服务端按版本号合并并只允许前进,任何一端读到的是同一份最新进度。

Q:学员换设备接着看,怎么从上次位置继续?

A:续学接口按课时返回已确认的最新合法位置,并在客户端做钳制(不小于 0、不超过课时总长),配合完成态标记,实现跨设备无缝续学。

Q:进度上报频率高,会不会压垮数据库?

A:上报先写 Redis 暂存并去重,定时批量落库;读取走缓存优先。数据库只承接合并后的最终进度,而不是每一次心跳。

Q:进度表和上报日志两张表会越攒越大吗?

A:进度表每学员每课一条,体量可控;上报日志按天分区,超过 30 天可归档或清理。保留足够窗口用于回放排查,不用长期全量保留。

结语

多端学习进度同步的核心不是"存得快",而是"合并得对"。本文方案仅作技术分享,具体实现按自身业务取舍。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、学员在手机、平板、网页端的学习进度怎么保持一致
  • 二、进度上报怎么保证不丢、不重复
  • 三、多个设备同时看,进度冲突怎么合并
  • 四、进度读取怎么做才不拖垮服务
  • 五、断点续学的位置怎么防回退
  • 踩坑清单
  • 工程落地建议
  • 上线复盘清单
  • 常见问题
  • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档