Skip to content
bitzorcas
中EN

Guide

迁移、指定节点发起与旧实例导入

区分 StartAtNode 与 Import,讲解映射、预检、当前非事务/非幂等边界、批次恢复、申请人转交和验收 Runbook。

Last updated

Workflow 有两条不同的迁移路径:StartAtNode 使用当前引擎真实执行目标节点;ImportInstance 直接重建旧系统实例、Execution、Task 和一条 Import 轨迹。前者适合补建流程,后者适合大规模在途迁移。

1. 选择路径

场景使用
业务已存在,希望从新定义某节点继续StartAtNode
业务已完成,只补一条完成实例StartAtNode(autoComplete=true)
要保留旧任务的审批人和创建时间ImportInstance
人员离职,迁移当前申请人TransferApplicant / TransferAllByUser
运行中实例回到某节点修复ResetToNode,需严格管理权限

2. StartAtNode

它解析当前 Active 定义,验证 target node,创建实例和 Start 轨迹。autoComplete=false 时创建 Execution 并执行目标节点;true 时直接把实例设为 Completed,不创建目标任务。

从审批节点补建立案
Result<IProcessInstance> migrated =
await migration.StartAtNodeAsync(
// 业务键必须能与旧系统案件记录一一对账。
definitionKey: "matter-intake-approval",
businessKey: legacyMatter.MatterNo,
businessType: "MatterIntake",
starterId: legacyMatter.ApplicantId,
tenantId: currentTenantId,
officeId: legacyMatter.OfficeId,
startNodeId: "partner-review",
autoComplete: false,
// 映射变量应在预检阶段完成类型与必填项校验。
variables: mappedVariables,
skipReason: "Legacy migration batch 2026-08",
cancellationToken);

注释称前置节点会标记 Skipped/Completed,但当前实现只写一条 Start Activity 指向目标节点,没有逐前置节点生成轨迹。文档和迁移报告不能声称拥有完整跳过链。

StartAtNode 同样没有 source id/idempotency key;重复调用可能创建多个实例。

3. ImportInstance 请求

请求包含 SourceSystem、SourceInstanceId、DefinitionKey、TenantId、OfficeId、BusinessKey/Type、Starter、CurrentNode、FlowState、Status、Variables、ActiveTasks 与 OriginalStartTime。

旧实例导入请求
{
"sourceSystem": "legacy-oa",
"sourceInstanceId": "WF-2021-00981",
"definitionKey": "matter-intake-approval",
"tenantId": "tenant-a",
"officeId": "shanghai",
"businessKey": "(2026)沪仲案字第0981号",
"businessType": "MatterIntake",
"starterId": "1001",
"starterName": "立案秘书",
"currentNodeId": "partner-review",
"currentNodeName": "主办合伙人复核",
"flowState": "BW",
"status": "Running",
"variables": {
"disputeAmount": 1850000
},
"activeTasks": [
{
"nodeId": "partner-review",
"nodeName": "主办合伙人复核",
"assigneeId": "2008",
"taskStatus": "Pending",
"createTime": "2026-06-20T02:00:00Z"
}
],
"originalStartTime": "2026-06-18T08:00:00Z"
}

HTTP 端点由认证与 IAuthorizedRequest(Create workflow/instance) 保护,但 TenantId 来自请求对象,不是 Handler CurrentUser。管理员跨租户导入必须有显式平台权限和审计。

此外,导入命令实现了 ILicensedMigrationRequest 标记:商业环境的在途迁移同样经过 Runtime License 门禁,未获许可的部署无法调用该入口。

4. 当前定义选择

ManagementService 通过 ListDefinitionsAsync(definitionKey, tenantId) 取 versions[0],没有按部署绑定,也没有明确排序为最新。导入可能锁定错误版本。正确设计应要求调用者提供 DefinitionId/Version,并验证目标节点存在。

同一问题也影响 RefreshCandidates:它没有按实例 DefinitionId 读取规则。

5. 当前非事务边界

Import 依次保存 Instance、每个 Execution、每个 Task,最后保存 ActivityRecord,没有 BeginTransaction。任一步失败会留下部分数据。

PersistenceManagementServiceMigration clientPersistenceManagementServiceMigration clientloop[each active task]中途失败没有自动清理ImportInstanceSave instanceSave executionSave taskSave import activitySuccess

必须把单实例所有写入同一事务,并为 SourceSystem+SourceInstanceId+TenantId 建唯一导入记录。

6. 当前校验缺口

Import 不验证:

  • CurrentNodeId 是否存在于锁定定义;
  • ActiveTask.NodeId 是否存在或等于当前节点;
  • Assignee 是否存在于当前租户;
  • Status/TaskStatus 非法值(非法时静默回退 Running/Pending);
  • FlowState 与 Status 是否一致;
  • BusinessKey 是否已有实例;
  • Variables 是否符合大小/类型策略;
  • SourceInstanceId 是否已经导入。

这些校验应先生成 dry-run 报告,P0 错误阻断,warning 需人工签字。

7. 批量导入

ImportInstancesBatchAsync 顺序处理请求并报告进度;每项失败被包装到结果,整个方法仍返回 Success。它没有 checkpoint、并发控制、暂停/恢复或失败导出。

批处理应按稳定批次 ID 保存 manifest:

batchId
sourceSystem
sourceSnapshotChecksum
definitionMappingVersion
startedAt / completedAt
item sourceId -> status / newInstanceId / error
operator / approver
rollback status

重启后只继续未完成项;成功项通过幂等键返回原 NewInstanceId。

8. 申请人转交

TransferApplicant 允许当前申请人或 Manage 权限操作,在事务中更新 applicant 与轨迹。TransferAllByUser 查询租户内活跃实例后逐项转交,返回逐实例失败,不是全有或全无。

fromUserId 参数当前主要用于说明,实际权限判断使用 CurrentApplicant 与 operatedBy;迁移工具仍应验证原申请人一致,避免错误批次。

9. 回滚策略

在当前非事务/非幂等实现下,不建议直接对生产运行大批。若必须迁移:

  1. 数据库快照并冻结旧流程写入;
  2. 小批 dry-run 和人工映射审核;
  3. 每项前后查询并记录新 ID;
  4. 失败立即停止,检查部分 Instance/Execution/Task;
  5. 只通过受审脚本清理该批次创建的数据;
  6. 对账业务键、任务数、审批人、状态和轨迹;
  7. 恢复旧系统前确认没有新引擎动作。

10. 验收

  • 源实例数 = 成功 + 明确失败;
  • SourceId 到 NewInstanceId 一一对应;
  • 定义版本与发布映射正确;
  • 每个 Pending Task 可被正确用户查询和操作;
  • 跨租户不可见;
  • 完成一个抽样任务可继续真实流转;
  • 通知、Timer 和缓存按预期重建;
  • 批次可重放且不产生重复;
  • 回滚脚本经过非生产演练。

11. 源码核查

Terminal window
rg -n "ImportInstanceAsync|SaveInstanceAsync|SaveExecutionAsync|SaveTaskAsync" src/Framework/BitzOrcas.Workflow/BitzOrcas.Workflow.Engine/Services/ManagementService.cs
rg -n "SourceInstanceId|BeginTransactionAsync|versions\[0\]" src/Framework/BitzOrcas.Workflow src/Platform/Workflow -g '*.cs'

定义本身由 Workflow Migrator 从 BitzOrcas 或 Saury 旧表转入 JSON DSL。本页的 Import 与定义迁移互补:先有已发布定义,再导入在途实例。

下一篇:通知 Pipeline

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%