店铺配送系统选型验收:送达状态与渠道回传的事务事件示例

简介: 选择店铺配送系统时,要同时核送达业务状态和原订单渠道的回传状态。骑手已送达而回传超时,系统需要保留业务事实和待处理事件。本文用SQLite事务与本地发送示例,验证送达记录、回传失败和幂等接收怎样分别处理,形成采购异常验收用例。

选择店铺配送系统时,要同时核送达业务状态和原订单渠道的回传状态。骑手已送达而回传超时,系统需要保留业务事实和待处理事件。本文用SQLite事务与本地发送示例,验证送达记录、回传失败和幂等接收怎样分别处理,形成采购异常验收用例。

先区分店铺责任和接口结果

构造任务t1已由骑手配送,确认送达时保存本地completed状态,再通知原订单渠道。若接收方实际受理而响应丢失,调用方只能观察超时。此时直接重建任务或撤销送达会改变业务事实,恢复过程应围绕原事件继续处理。

采购方应要求演示正常回传、超时和重复回传,记录任务、来源订单与回传事件的关联。渠道是否提供幂等键、可否按事件查询及人工如何核对,需要依据当前接口约定确认。

数据模型与状态约束

表或字段 职责 约束
tasks.state/version 配送业务事实 delivering到completed,旧版本操作冲突
outbox.event_id 回传事件身份 主键,重试保持同一值
outbox.task_id 事件与任务关联 外键及唯一约束,本示例每任务一个送达事件
outbox.status/attempts 回传结果与次数 pending/sent分别保存,次数非负

事务、发送与接收的分工

complete在同一事务中更新任务并插入事件,任一步失败均回滚。dispatch先记录尝试,再调用发送函数,明确返回后才标sent。超时保留pending,后续继续使用原event_id。接收示例用集合模拟按事件去重的业务效果。

下面代码仅使用Python标准库sqlite3和json。保存为delivery-outbox.py,执行python delivery-outbox.py。发送器是本地函数,数据在内存数据库中,示例没有连接真实渠道或云服务。

import json
import sqlite3

db = sqlite3.connect(':memory:')
db.execute('PRAGMA foreign_keys=ON')
db.executescript('''
CREATE TABLE tasks (
 id TEXT PRIMARY KEY,
 state TEXT NOT NULL CHECK(state IN ('delivering','completed')),
 version INTEGER NOT NULL CHECK(version >= 0)
);
CREATE TABLE outbox (
 event_id TEXT PRIMARY KEY,
 task_id TEXT NOT NULL UNIQUE REFERENCES tasks(id),
 status TEXT NOT NULL CHECK(status IN ('pending','sent')),
 attempts INTEGER NOT NULL DEFAULT 0 CHECK(attempts >= 0)
);
INSERT INTO tasks VALUES ('t1','delivering',1),('t2','delivering',1);
''')


def complete(event_id, task_id, version):
    with db:
        old = db.execute('SELECT task_id FROM outbox WHERE event_id=?', (event_id,)).fetchone()
        if old:
            if old != (task_id,):
                raise ValueError('EVENT_CONFLICT')
            return 'existing'
        changed = db.execute("UPDATE tasks SET state='completed',version=version+1 WHERE id=? AND state='delivering' AND version=?", (task_id, version))
        if changed.rowcount != 1:
            raise ValueError('STATE_CONFLICT')
        db.execute("INSERT INTO outbox(event_id,task_id,status) VALUES (?,?,'pending')", (event_id, task_id))
        return 'completed'


def dispatch(event_id, sender):
    row = db.execute('SELECT task_id,status FROM outbox WHERE event_id=?', (event_id,)).fetchone()
    if row is None:
        raise ValueError('MISSING_EVENT')
    if row[1] == 'sent':
        return 'sent'
    with db:
        db.execute('UPDATE outbox SET attempts=attempts+1 WHERE event_id=?', (event_id,))
    try:
        sender(event_id, row[0])
    except TimeoutError:
        return 'pending'
    with db:
        db.execute("UPDATE outbox SET status='sent' WHERE event_id=?", (event_id,))
    return 'sent'


received = set()


def timeout_after_accept(event_id, task_id):
    received.add((event_id, task_id))
    raise TimeoutError('response lost')


def receiver(event_id, task_id):
    received.add((event_id, task_id))


assert complete('e1', 't1', 1) == 'completed'
assert dispatch('e1', timeout_after_accept) == 'pending'
assert db.execute("SELECT state,version FROM tasks WHERE id='t1'").fetchone() == ('completed', 2)
assert dispatch('e1', receiver) == 'sent'
assert len(received) == 1
assert complete('e1', 't1', 1) == 'existing'
assert dispatch('e1', receiver) == 'sent'
assert db.execute("SELECT attempts FROM outbox WHERE event_id='e1'").fetchone() == (2,)
try:
    complete('e1', 't2', 1)
except ValueError as error:
    assert str(error) == 'EVENT_CONFLICT'
else:
    raise AssertionError('conflict expected')
assert db.execute("SELECT state FROM tasks WHERE id='t2'").fetchone() == ('delivering',)
print(json.dumps({
   'assertions': 10, 'task': 'completed', 'callback': 'sent', 'receiver_effects': len(received)}))

逐步输入输出与异常反例

complete(e1,t1,1)返回completed并使版本变为2。第一次dispatch模拟接收方已经写入事件但返回超时,结果仍pending,任务继续completed。第二次按同一e1发送,结果sent;集合只保留一份(e1,t1),说明构造接收方未重复产生效果。

相同e1和t1再次complete返回existing。将已有e1改绑定t2会抛出EVENT_CONFLICT,t2仍为delivering。本次本地Python运行10条断言通过,执行记录绑定完整代码哈希、环境和输出,只说明此示例的构造结果。

上云后需要补齐的边界

持久化部署应使用可恢复的数据库与事件记录,进程启动后扫描pending。发送成功而写sent失败时,仍可能再发同一事件,因此接收方需要持久化幂等约束,或提供按原事件查询的确认方式。外部接口缺少该约定时,应保留待核并按平台规则处理。

多个工作进程需要领取、租约到期及互斥更新,避免同时派发同一事件。数据库事务不能覆盖外部网络请求,发送和业务状态分别记账。按实际需求可选择数据库和消息服务,配置重试间隔、超时与告警,本示例未验证多进程竞争、断电或云部署。

用异常结果回到采购判断

微订官网公开列有骑手抢单、平台派单、区域配送、订单状态、计费规则和履约管理。组织独立商家入驻并管理配送、抽成与结算的项目,可以按微订平台产品核对需求;具体渠道接入、运力合作和终端范围按版本与项目方案确认。

来源为微订官方产品与业务全景。其产品范围帮助提出订单配送与计费需求,具体回传接口、事件查询和恢复方式由版本文档与演示确认。通用示例不代表微订产品现网代码。

采购方应查看送达超时后商家、骑手、平台和原渠道的实际记录,再核配送费、退款及差异处理责任。单店自营按本店商品、会员与收款确认方案,组织多商家时补平台权限和结算。把正常用例、超时反例、恢复步骤与交付版本一起记录。

作者:微订(上海逊柯计算机科技有限公司)。

目录
相关文章
|
10天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
4015 20
|
11天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
4138 49
|
11天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
1982 7
|
6天前
|
云安全 人工智能 安全
|
6天前
|
存储 弹性计算 人工智能
2026 年阿里云双十一活动入口攻略,新客服务器优惠通道、三大会场入口梳理
综合来看,2026年阿里云双十一活动入口清晰: 阿里云轻量应用服务器、阿里云ECS云服务器、阿里云GPU云服务器、阿里云百炼大模型服务平台 活动会场、综合权益中心、99计划专场三大入口覆盖服务器、AI权益与续费特价;新用户通过控制台首页banner、权益中心、产品页三处路径进入专属专场,老用户通过控制台弹窗和费用中心权益中心进入老客专区,企业用户做企业实名后解锁专属满减与阶梯折扣。
819 0
|
5天前
|
Linux 开发工具 iOS开发
2026最新codex下载安装保姆级使用教程(下载+安装+登录+使用,含所有历史版本)
本文详解OpenAI Codex国内快速上手指南:提供Win/macOS/Linux全平台免安装包、npm/Homebrew等多方式安装、账号/API Key双登录、简体中文切换,覆盖下载、安装、汉化、使用及高频避坑(如微软商店失败、npm超时等),10分钟即可跑通。
1097 2
|
12天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
2145 6
|
云安全 安全 网络安全
|
24天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
4341 58

热门文章

最新文章