| name | validate-then-transact |
| description | MallBase ThinkPHP 写操作与事务规则;实现或修改 create、update、delete、状态流转、多表写入、余额库存变更、行锁、条件更新或并发一致性校验时使用。 |
ThinkPHP 校验与事务边界
默认顺序
- 在事务外完成参数格式、权限、静态业务规则和不依赖锁的存在性检查。
- 只在需要原子多表写入或并发一致性时开启事务。
- 在事务内保持查询和写入最少,完成后立即提交。
- 把远程 API、短信、推送、文件处理等慢或不可回滚的外部 I/O 放到事务外;需要可靠副作用时使用提交后的事件或队列方案。
$this->validateBusiness($data);
return $this->transaction(function () use ($data): int {
$model = $this->model();
$model->save($data);
return (int) $model->id;
});
并发校验例外
“先校验再事务”不等于禁止事务内校验。余额、库存、订单状态、退款额度等值可能在事务外检查后被并发修改,必须在事务内重新读取可信当前状态:
return $this->transaction(function () use ($id): bool {
$row = $this->model()->where('id', $id)->lock(true)->find();
if ($row === null) {
throw new BusinessException('记录不存在');
}
if (!$this->canTransit((int) $row->status)) {
throw new BusinessException('当前状态不允许操作');
}
return $row->save(['status' => 2]);
});
在热点计数或库存扣减中,优先使用带条件的原子 UPDATE,再根据受影响行数判断是否冲突。唯一约束、条件更新和行锁是并发下的最终防线,事务外预检不能替代它们。
禁止项
- 不为单表单次写入机械地扩大事务范围。
- 不在持锁事务内调用外部服务或执行可长时间阻塞的工作。
- 不只依赖事务外读取做状态流转、余额或库存判断。
- 不吞掉事务异常后返回成功。
自检