并发提交与审批顺序一致性

[复制链接]
发表于 2025-10-20 10:53:14 | 显示全部楼层 |阅读模式

answer from Qwen

这是一个典型的并发提交与审批顺序一致性问题。核心诉求是:

当业务A的“类型1”多次提交到业务B的“类型1”进行审核时,即使多次提交并发发生,最终审核通过的结果必须反映最新的提交内容,且审批流程应按提交顺序执行(或至少结果体现最新状态)。


一、问题本质分析

  • 多次提交:业务A类型1可多次提交,每次生成一条待审记录(提交版本)。
  • 审批流程:业务B类型1对每条提交记录进行审核。
  • 目标
    1. 顺序性:先提交的应先审核(可选,但有助于逻辑清晰)。
    2. 最终一致性:无论中间过程如何,最终审核通过的结果必须是最后一次提交的内容
    3. 避免过期审批:不能让旧提交在新提交之后被批准并覆盖新状态。

二、解决方案设计

✅ 核心思路:版本控制 + 状态锁 + 审批有效性校验

1. 引入“提交版本号”或“时间戳”字段

每次业务A类型1提交时,系统自动生成一个递增的版本号(或使用高精度时间戳):

{
  "submit_id": "S123",
  "biz_a_type": "type1",
  "biz_b_type": "type1",
  "content": "...",
  "version": 3,               // 递增整数,或使用UUID+时间戳组合
  "submit_time": "2025-10-20T10:00:00Z",
  "status": "pending"
}

建议使用单调递增整数版本号(如数据库自增ID或业务级版本计数器),比时间戳更可靠(避免时钟漂移)。


2. 业务B审核时,强制校验“是否为最新提交”

在审批操作(通过/拒绝)时,执行以下逻辑:

def approve_submission(submit_id):
    submission = get_submission(submit_id)
    latest = get_latest_pending_or_approved_submission_for(biz_a_type="type1", biz_b_type="type1")
    
    if submission.version < latest.version:
        raise Exception("该提交已过期,存在更新的提交,请审核最新版本。")
    
    # 正常执行审批逻辑
    mark_as_approved(submission)

这样即使旧提交还在审批队列中,一旦有新提交,旧提交就无法被批准(或自动作废)。


3. 自动作废旧提交(推荐)

当业务A类型1再次提交时,系统自动将该业务对(A类型1 → B类型1)下所有未完成(pending)的旧提交标记为“已废弃”

def submit_from_a_to_b(content):
    # 1. 查询当前未完成的提交
    pending_subs = query_pending_submissions(
        biz_a_type="type1", 
        biz_b_type="type1"
    )
    
    # 2. 标记为废弃
    for sub in pending_subs:
        sub.status = "abandoned"
        save(sub)
    
    # 3. 创建新提交
    new_version = get_next_version("type1->type1")
    new_sub = create_submission(
        content=content,
        version=new_version,
        status="pending"
    )
    return new_sub

✅ 优点:审批人员只看到最新提交,避免混淆;系统逻辑清晰。


4. 审批界面优化(用户体验)

  • 在业务B的审批列表中,只展示每个业务对的最新提交(或明确标注“此为旧版本,已被新提交替代”)。
  • 若审批人试图审批旧版本,前端/后端提示:“该申请已被更新,请审批最新版本”。

三、可选增强:审批队列顺序控制

如果业务要求严格按提交顺序审批(即使有新提交,也要先审完旧的),则需引入审批队列 + 状态锁

  • 使用一个FIFO队列管理待审任务。
  • 每次提交入队,审批时从队首取。
  • 但审批通过前,检查是否为最新版本(同上)。
  • 若不是最新,则跳过(或自动拒绝),继续处理下一个。

⚠️ 注意:这种模式可能导致审批积压,且最终结果仍需以最新提交为准,因此**“自动废弃旧提交”通常是更优解**。


四、数据库设计建议

CREATE TABLE submission (
    id BIGINT PRIMARY KEY,
    biz_a_type VARCHAR(50) NOT NULL,
    biz_b_type VARCHAR(50) NOT NULL,
    content JSON,
    version INT NOT NULL,                 -- 业务对内的递增版本
    status ENUM('pending', 'approved', 'rejected', 'abandoned') DEFAULT 'pending',
    submit_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_biz_pair_status (biz_a_type, biz_b_type, status),
    INDEX idx_version (biz_a_type, biz_b_type, version DESC)
);

查询最新提交:

SELECT * FROM submission 
WHERE biz_a_type = 'type1' 
  AND biz_b_type = 'type1'
  AND status IN ('pending', 'approved')
ORDER BY version DESC 
LIMIT 1;

五、总结:推荐方案

目标 实现方式
保证最终结果为最新提交 每次新提交时,自动废弃旧的 pending 提交
防止旧提交被误审 审批时校验版本号,非最新则拒绝
简化审批流程 审批列表只展示最新 pending 提交
可追溯历史 保留所有提交记录(含 abandoned),供审计

最终效果:无论业务A提交多少次,业务B只会审批最新的一次,且审批通过后系统状态即为最新提交内容,满足业务一致性要求。

如需进一步结合具体技术栈(如 Kafka、Redis、工作流引擎等),可继续补充场景细节。

change of mine

处理不同状态的数据

image.png

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

GMT+8, 2025-10-28 02:27 , Processed in 0.075295 second(s), 35 queries Archiver|手机版|小黑屋|Attic ( 京ICP备2020048627号 )

快速回复 返回顶部 返回列表