在CakePHP TreeBehavior中使用事务?

我们已经将CakeBehavior和CakePHP 3.6一起使用了一段时间。最近,在一棵大树(大约90000个节点)下,我们遇到了问题。

删除节点时,在cakephp / src / ORM / Behavior / TreeBehavior中调用beforeDelete()函数:

    /**
     * Also deletes the nodes in the subtree of the entity to be delete
     *
     * @param \Cake\Event\Event $event The beforeDelete event that was fired
     * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved
     * @return void
     */
    public function beforeDelete(Event $event,EntityInterface $entity)
    {
        $config = $this->getconfig();
        $this->_ensureFields($entity);
        $left = $entity->get($config['left']);
        $right = $entity->get($config['right']);
        $diff = $right - $left + 1;
        if ($diff > 2) {
            $query = $this->_scope($this->_table->query())
                ->delete()
                ->where(function ($exp) use ($config,$left,$right) {
                    /* @var \Cake\Database\Expression\QueryExpression $exp */
                    return $exp
                        ->gte($config['leftField'],$left + 1)
                        ->lte($config['leftField'],$right - 1);
                });
            $statement = $query->execute();
            $statement->closeCursor();
        }
        $this->_sync($diff,'-',"> {$right}");
    }

此函数调用_sync()函数以更新树的左右值:


    /**
     * Auxiliary function used to automatically alter the value of both the left and
     * right columns by a certain amount that match the passed conditions
     *
     * @param int $shift the value to use for operating the left and right columns
     * @param string $dir The operator to use for shifting the value (+/-)
     * @param string $conditions a SQL snipped to be used for comparing left or right
     * against it.
     * @param bool $mark whether to mark the updated values so that they can not be
     * modified by future calls to this function.
     * @return void
     */
    protected function _sync($shift,$dir,$conditions,$mark = false)
    {
        $config = $this->_config;
        foreach ([$config['leftField'],$config['rightField']] as $field) {
            $query = $this->_scope($this->_table->query());
            $exp = $query->newExpr();
            $movement = clone $exp;
            $movement->add($field)->add((string)$shift)->setConjunction($dir);
            $inverse = clone $exp;
            $movement = $mark ?
                $inverse->add($movement)->setConjunction('*')->add('-1') :
                $movement;
            $where = clone $exp;
            $where->add($field)->add($conditions)->setConjunction('');
            $query->update()
                ->set($exp->eq($field,$movement))
                ->where($where);
            $query->execute()->closeCursor();
        }
    }

但是,似乎此_sync()函数执行的更新查询未包装在事务中,并且看起来像这样:

UPDATE `leafs` SET `lft` = ((`lft` - 12)) WHERE ((`lft`  > 52044))
UPDATE `leafs` SET `rght` = ((`rght` - 12)) WHERE ((`rght`  > 52044))

这些不应该像这样包装在交易中吗?

START TRANSactION
UPDATE `leafs` SET `lft` = ((`lft` - 12)) WHERE ((`lft`  > 52044))
UPDATE `leafs` SET `rght` = ((`rght` - 12)) WHERE ((`rght`  > 52044))
COMMIT

...尤其是因为更新的值(lft和rght)也出现在WHERE子句中。我们在树损坏方面遇到了一些问题,并想知道这是否可能是一个原因……尤其是当在一棵大树上快速连续执行多个操作时。

Jasonxxxyyy 回答:在CakePHP TreeBehavior中使用事务?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3167315.html

大家都在问