在Laravel+Vuejs项目中如何实现联网时离线IndexedDB同步到线上Oracle数据库
离线数据同步功能实现方案
前端(Vue2 + IndexedDB)侧实现
- 首先为IndexedDB中的产品、发票表新增必填元字段:
sync_status:枚举值,可选pending(待同步)/success(同步成功)/failed(同步失败)sync_attempts:数值型,记录同步失败重试次数,默认0local_uuid:前端生成的唯一UUID,用于后端做幂等校验operation_type:枚举值,可选create/update/delete,支持后续扩展离线改删操作created_local_at:本地操作时间戳,用于保证同步时序
- 封装全局数据写入逻辑:所有用户发起的产品、发票写操作,先通过
navigator.onLine判断网络状态:- 在线状态直接调用线上接口,接口报错(比如网络闪断、服务端异常)时自动降级写入IndexedDB,标记
sync_status = pending - 离线状态直接写入IndexedDB,标记
sync_status = pending
- 在线状态直接调用线上接口,接口报错(比如网络闪断、服务端异常)时自动降级写入IndexedDB,标记
- 绑定网络状态监听事件:
// Vue2 入口文件(main.js)中注册监听 window.addEventListener('online', () => { // 网络恢复时触发同步任务 executeSyncTask() }) - 同步任务逻辑实现:
- 从IndexedDB中查询所有
sync_status = pending的记录,按created_local_at升序排序,优先同步更早的操作,避免发票关联产品时先同步发票导致外键报错 - 按接口限制批量拼接待同步数据,调用后端同步接口
- 根据接口返回结果更新IndexedDB记录:同步成功的记录可直接删除或标记
sync_status = success;同步失败的记录sync_attempts自增1,重试超过3次则标记sync_status = failed,前端弹出提示告知用户存在同步失败数据,支持手动触发重试
- 从IndexedDB中查询所有
后端(Laravel + Oracle)侧实现
- 新增专属同步接口
POST /api/offline/batch-sync,支持批量接收产品、发票待同步数据 - 接口逻辑处理:
- 首先做幂等校验:根据前端传的
local_uuid查询Oracle中是否已有对应记录,存在则直接返回该条同步成功,避免重复写入 - 数据校验规则和普通产品、发票创建接口完全一致,避免脏数据入库
- 所有同步操作包裹在数据库事务中,保证同批次数据要么全部写入成功要么全部回滚,避免部分同步的异常状态
- 返回结果按条标注同步状态,失败数据返回明确错误原因,方便前端更新本地状态
- 首先做幂等校验:根据前端传的
边缘场景兼容
- 应用初始化(页面加载)时判断如果处于在线状态,自动执行一次同步任务,避免用户上次关闭应用时存在未同步数据
- 待同步数据量较大时做分页处理,单次同步控制在20~50条,避免请求体过大导致超时
- 同步过程中如果触发
offline事件,立即终止当前同步任务,下次网络恢复时继续执行未完成的同步
内容的提问来源于stack exchange,提问作者Abdul Basit
相关产品推荐
相关产品推荐

