事务、一致性与上限
一个 Action 就是一个事务。普通批量最多 20 个请求,writeback 只接受单请求;一次最多改 10,000 个对象;编辑 Function 的编辑由 Action 统一提交。

本课目标
读完这一课,你将能够
- 说出「一个事务」保证什么、不保证什么
- 用批量执行处理一批请求,说出并发冲突时会怎样,以及各项上限
- 说出 Function 驱动的 Action 解决什么问题,以及 AIDC 的现状
一个 Action 就是一个事务
一个 Action 的编辑是一个事务:读、算、写一起发生,写入要么全部生效,要么全部不生效。这就是常说的 ACID:原子性(全有或全无)、一致性(不满足值类型约束、必填等就不提交)、隔离性(并发时互不串扰)、持久性(提交后永久保存)。一个 Action 完成之后开始的任何 Action 和查询,都能看到它的全部编辑。
原子性只覆盖对象上的编辑,不覆盖通知和 Webhook,也不覆盖 Function 里的外部调用。示例工厂的 ship-order 是个好例子:新建发运单,再把订单改成 shipped,两条规则在同一个事务里。
{
"kind": "actionType",
"apiName": "ship-order",
"title": "发运订单",
"schema": {
"parameters": [
{ "name": "order", "type": "object", "objectType": "salesOrder", "title": "订单", "required": true },
{ "name": "carrier", "type": "string", "title": "承运商", "required": true, "maxLength": 60 }
],
"rules": [
{
"type": "createObject",
"objectType": "shipment",
"values": { "shipmentNo": "$uuid", "carrier": "$carrier", "status": "shipped", "shippedAt": "$now", "orderNo": "$order.orderNo" }
},
{ "type": "modifyObject", "objectType": "salesOrder", "object": "$order", "values": { "status": "shipped" } }
],
"submissionCriteria": [
{
"condition": { "type": "comparison", "left": { "param": "order", "property": "status" }, "operator": "is", "right": { "literal": "inProduction" } },
"failureMessage": "只有生产中的订单可以发运"
}
],
"actionLog": true
}
}
不会出现「订单已经发运,却没有发运单」,也不会出现相反的情况。日志对象也在这个事务里。
批量与并发
用 applyBatch 一次处理多张工单的产出。普通批量最多 20 个请求;配置 writeback webhook 的 Action 只能单请求提交。批量先全部校验,任何一个不通过就不执行。整批编辑在一个事务里,遇到冲突整批回滚。
aidc semantic apply-batch report-output reports.json --return-edits
[
{ "workOrder": "WO-2001", "goodQty": 120 },
{ "workOrder": "WO-2002", "goodQty": 80, "scrapQty": 2 }
]
上面是 reports.json 的样子:一个数组,每项是一次请求的参数。并发是另一件事:两个人同时改同一个对象,谁生效?通用做法用隔离级别回答。缺省的快照隔离让一个 Action 读到的所有数据都来自它开始的那一刻;它要写的对象如果在这期间被别的 Action 改过,它就失败,而不是悄悄覆盖。遇到冲突可以自动重试,最多 5 次,含外部调用的 Action 默认不重试。
上限
超过上限不会部分成功,整个请求会被拒绝,并说明是哪一项超了。
AIDC 普通批量最多 20 个请求;有 writeback 的 Action 不接受 applyBatch。处理更多对象,要拆成多次调用。每次自成一个事务,整体不再是一个事务。事先想好中途停下的状态,比如把批次号写进参数,让日志帮你续跑。
规则不够用时:Function 驱动的 Action
规则只描述声明式改动。需要读取多个对象并计算时,可以用编辑 Function。Function 按调用人的权限读对象,用 ctx.edits 产生对象和链接的编辑。Action 统一提交这些编辑。Action 的规模上限和 Function 的执行上限仍然生效。
下一门课《Function 与逻辑》从这里接着讲:什么该用声明式构件,什么该写成代码,以及怎样测试。
要点
- 一个 Action 是一个事务:对象上的编辑与日志要么都生效,要么都不生效;通知和 Webhook 不在里面。
- 普通批量最多 20 个请求,先全部校验,一个事务,冲突整批回滚。配置 writeback 的 Action 只能单请求提交。
- 一次最多改 10,000 个对象、涉及 50 个对象类型;超过整个请求被拒绝。
- 编辑 Function 在隔离运行时里读取对象并计算,用
ctx.edits产生编辑,Action 统一提交。
练一练
批量、拆分与判断
第一个任务会写入数据,请在你有权限写入的测试组织里做。
准备一个 reports.json,里面三条 report-output 请求。先对每条运行 aidc semantic apply report-output --validate-only,再用 aidc semantic apply-batch report-output reports.json --return-edits 一次提交,比较返回的 edits。
判断四件事能否放进同一个 Action 事务,并说明理由:新建发运单并改订单状态;改订单状态并发一封邮件;一次改 15,000 个对象;把 MES 里的工单状态改回去。
要把 15,000 张工单暂停。设计怎么拆:每批多少张,批次号放在哪个参数里,中途失败后怎样借日志续跑。
小测
选一个答案,马上看解析。
Q1用 applyBatch 提交 20 个 report-output,第 12 个在执行时碰到并发冲突,结果是什么?
批量执行是一个事务:校验先全部做完,执行时任何一个冲突,整批回滚。
Q2用一个对象集参数一次暂停 12,000 张工单,会怎样?
上限不会部分成功。拆开之后每次自成一个事务,要事先想好中途停下的状态。
Q3receive-material 想把收货数量加到库存上,在 AIDC 里今天该怎么做?
声明式规则不做计算。编辑 Function 已可读取对象并计算,通过 ctx.edits 产生编辑,由 Action 统一提交。