如何在事务期间运行影响实体的查询



我正在尝试遍历一些实体并更新step_order列,然后从该列中减去一个值。举个例子:

  1. 从这些实体开始

    ID | step_order
    1  | 1
    2  | 2
    3  | 3
    4  | 4
    
  2. 更改顺序

    ID | step_order
    1  | 6
    2  | 5
    3  | 7
    4  | 8
    
  3. 从顺序中减去 4 以使值恢复为 1

    ID | step_order
    1  | 2
    2  | 1
    3  | 3
    4  | 4
    

这是我的代码,删除了不相关的部分:

在管理器内

$nextOrder = $this->stepRepo->findNextOrder($maintenanceId);
$steps = [];
foreach ($order as $o => $stepId) {
$step = $this->getStep($stepId);
$steps[] = $step;
}
$this->em->beginTransaction();
foreach ($steps as $o => $step) {
$step->setStepOrder($nextOrder + $o);
$this->em->persist($step);
}
$this->stepRepo->subtractOrder($maintenanceId, $nextOrder - 1);
$this->em->commit();
$this->em->flush();
public function getStep($id)
{
return $this->stepRepo->find($id);
}

在步骤回购内

public function subtractOrder($maintenanceId, $amount)
{
$maintenanceId = (int) $maintenanceId;
$qb = $this->createQueryBuilder('s');
$qb->update()
->set('s.stepOrder', 's.stepOrder - :amount')
->where('s.maintenanceId = :maintenanceId')
->setParameter('amount', $amount)
->setParameter('maintenanceId', $maintenanceId);
$result = $qb->getQuery()->execute();
return $result;
}

我期望发生的事情如下:

  1. 选择最大值(step_order(
  2. 开始交易
  3. 更新每个实体的step_order
  4. 运行查询更新所有step_orders = step_order - MAX(step_order(

发生了什么事情:

  1. 选择最大值(step_order(
  2. 开始交易
  3. 运行查询更新所有step_orders = step_order - MAX(step_order(

以下是symfony分析器的输出:

SELECT MAX(l0_.step_order) AS sclr_0 FROM lsp_maintenance_step l0_ WHERE l0_.maintenance_id = ?
Parameters: ['1']
"START TRANSACTION"
Parameters: { }
UPDATE lsp_maintenance_step SET step_order = step_order - ? WHERE maintenance_id = ?
Parameters: [4, 1]

这是MySQL错误:

An exception occurred while executing 'UPDATE lsp_maintenance_step SET step_order = step_order - ? WHERE maintenance_id = ?' with params [4, 1]:nnSQLSTATE[22003]: Numeric value out of range: 1690 BIGINT UNSIGNED value is out of range in '(`toolbox`.`lsp_maintenance_step`.`step_order` - 4)'

错误是正确的,因为从任何实体中减去 4 将使步长顺序保持在 0 或更小,这是不正确的。

为什么教义在更新实体之前运行最后UPDATE

为什么在更新实体之前,学说运行最后一个UPDATE

经过一些挖掘,我发现当EntityManager上调用flush()时,实体会提交,而execute()会立即运行。

为了解决这个问题,我使用了事务嵌套,其中实体在子事务中提交,UPDATE在主事务中调用。

$this->em->beginTransaction();
try {
$this->em->beginTransaction();
try {
foreach ($steps as $o => $step) {
$step->setStepOrder($nextOrder + $o);
$this->em->persist($step);
}
$this->em->flush();
} catch (Exception $e) {
$this->em->rollback();
throw $e;
}
$this->stepRepo->subtractOrder($maintenanceId, $nextOrder - 1);
$this->em->flush();
foreach ($steps as $step) {
$this->em->refresh($step);
}
} catch (Exception $e) {
$this->em->rollback();
}

相关内容

  • 没有找到相关文章

最新更新