调拨单同步实战:旺店通到MySQL的增量落库与表头表体双轨方案
这个策略解决什么问题(场景与价值)
调拨单同步看似只是「单据搬运」,但只要仓库跨地域、SKU 量大、单据状态在「待审核→部分出库→已入库」之间反复跳,漏单、重单、子表错位这三种问题就会同时出现。某零售企业在多仓调拨场景下,3 个月下来两边账面差异一度到上千行,根因几乎都落在「增量窗口没对齐」「主表和明细表没绑同一次写入」「状态字段被错误覆盖」上。
我们用轻易云数据集成平台(Qeasy)承接的「旺店通调拨单 → MySQL」这一条策略,核心目标就三件:按 transfer_id 做幂等、按时间窗做增量、一次性把表头和表体写进同一次事务。
数据流向与字段映射(源 → 中间层 → 目标)
源端是旺店通·企业奇门的 wdt.stock.transfer.query 接口,目标端是 MySQL 的 execute 写入动作。中间层由轻易云承担,主要做字段清洗、状态归一化与主子表拆分。
| 维度 | 源端(旺店通) | 中间层(轻易云) | 目标端(MySQL) |
|---|---|---|---|
| 主键 | transfer_id | 透传 | transfer_id 主表 / transfer_id+rec_id 子表 |
| 业务号 | transfer_no | 透传 | transfer_no |
| 增量窗口 | start_time / end_time | {{LAST_SYNC_TIME}} / {{CURRENT_TIME}} | 不落地,仅驱动拉取 |
| 仓库 | from_warehouse_no / to_warehouse_no | 编码映射集中管理 | from_warehouse_no / to_warehouse_no |
| 状态 | status(10/20/30/40/46/50/60/66/70/80/90) | 归一化为目标系统状态字典 | status |
| 明细 | 嵌套数组 | 拆为 details_list 走 1:N | jry_wdt_stock_transfer_details_list |
主表和子表都使用 REPLACE INTO,这意味着只要 transfer_id(子表再加 rec_id)命中,整行会被覆盖,自然实现「同一调拨单最新一版覆盖旧版本」。
在轻易云上如何配置
1. 源端接口
- API:
wdt.stock.transfer.query,方法 POST。 - 必填参数:
start_time用{{LAST_SYNC_TIME|datetime}}注入,end_time用{{CURRENT_TIME|datetime}},这样每轮调度天然形成滑动窗口。 - 选填但建议传的:
from_warehouse_no、to_warehouse_no,当企业按仓拆分通道时,一定要指定,否则会被「不支持一次推送多个仓库编号」这条限制卡住。 idCheck保持关闭,autoFillResponse打开,由平台自动接住分页。
2. 目标端 SQL
- 入口是
execute,主语句对应jry_wdt_stock_transfer,子语句对应jry_wdt_stock_transfer_details_list。 main_params接收主表动态参数,extend_params_2接收 1:N 扩展参数,字段名要与源端返回的details_list数组对齐。- 两张表统一用
REPLACE INTO,参数化用:transfer_id这种命名占位符,避免拼接 SQL。 idCheck建议打开,让平台用transfer_id做幂等校验。
3. 中间层处理
- 编码映射集中管理:把旺店通的仓库编码、自定义字典统一在一张映射表里维护,源端编码变一次,所有下游策略同步生效。
- 表头表体分阶段:先把主表行落库,再批量落子表,不要在循环里一条条写。
实施步骤
阶段一:增量起点
首次上线时,LAST_SYNC_TIME 设定为业务上「能接受的最早回溯点」,比如上线当天 00:00:00;跑通后立即改为平台自动维护的滚动游标。
阶段二:全量触发
对历史调拨单另起一条 transfer_no 维度的全量任务,跑一次就关闭,避免和增量互相踩。典型错误是「全量和增量共用一个游标」,结果全量跑完把增量起点改写,后续 12 个小时的数据全丢。
阶段三:调度频率
源策略 cron 设为 */11 * * * *,目标策略设为 3-59/11 * * * *,错开 3 分钟,给源端完成拉取和中间层处理留出窗口。这个细节很多客户现场容易忽略,踩坑见下文。
阶段四:状态机兜底
源端 status 字段值很多(从 10 到 90),轻易云侧加一道状态过滤,只把 >=40(已审核之后)的状态写入下游,避免把「编辑中」的单据也持久化,造成子表反复重写。
踩坑复盘
- 增量窗口和游标不对齐:源端按
start_time拉,游标却用created,旺店通的modified才是稳的。稳妥的做法是游标字段与start_time用同一个时间字段。 - 主子表分两次事务写:一旦中间失败,主表进了、子表没进,后续就再也补不齐。务必让平台把主表和子表绑在同一次
execute调用里。 status被REPLACE误覆盖:回写时如果只回写明细字段不带status,目标端状态会被旧值覆盖。写入字段集要显式列出,不要图省事。- 全量和增量共用游标:这是几乎每个新团队都会踩一次的雷。全量任务必须用独立游标,跑完即弃。
- 不指定
from_warehouse_no:多仓场景下,接口会因为「不支持一次推送多个仓库编号」直接报错,务必按仓拆通道或前置筛选。
适用场景与不适用场景
适用:旺店通作为 WMS 主干、MySQL 作为数据中台或 BI 底座、需要按 transfer_id 幂等落库的多仓调拨。
不适用:需要强一致事务、需要回写旺店通做反审核、或者单据量级小到不值得做增量的场景,直接走接口调用更简单。