模型事务

最后更新于:2022-04-02 05:14:37

                        [TOC]

模型事务

当进程执行多个数据库操作时,可能必须成功完成每个步骤,以便维护数据完整性。事务提供了确保在将数据提交到数据库之前已成功执行所有数据库操作的能力。

Phalcon中的事务允许您在成功执行时提交所有操作,或者在出现问题时回滚所有操作。

手动事务

如果应用程序仅使用一个连接并且事务不是非常复杂,则只需将当前连接移动到事务模式,然后提交或回滚操作是否成功,就可以创建事务:

<!--?php

use Phalcon\Mvc\Controller;

class RobotsController extends Controller
{
    public function saveAction()
    {
        // Start a transaction
        $this--->db-&gt;begin();

        $robot = new Robots();

        $robot-&gt;name       = 'WALL-E';
        $robot-&gt;created_at = date('Y-m-d');

        // The model failed to save, so rollback the transaction
        if ($robot-&gt;save() === false) {
            $this-&gt;db-&gt;rollback();
            return;
        }

        $robotPart = new RobotParts();

        $robotPart-&gt;robots_id = $robot-&gt;id;
        $robotPart-&gt;type      = 'head';

        // The model failed to save, so rollback the transaction
        if ($robotPart-&gt;save() === false) {
            $this-&gt;db-&gt;rollback();

            return;
        }

        // Commit the transaction
        $this-&gt;db-&gt;commit();
    }
}

隐式事务

现有关系可用于存储记录及其相关实例,这种操作隐式创建事务以确保正确存储数据:

<!--?php

$robotPart = new RobotParts();

$robotPart--->type = 'head';



$robot = new Robots();

$robot-&gt;name       = 'WALL-E';
$robot-&gt;created_at = date('Y-m-d');
$robot-&gt;robotPart  = $robotPart;

// Creates an implicit transaction to store both records
$robot-&gt;save();

独立事务

隔离事务在新连接中执行,确保所有生成的SQL,虚拟外键检查和业务规则与主连接隔离。这种事务需要一个事务管理器,它全局管理所创建的每个事务,确保在结束请求之前正确回滚/提交它们:

<!--?php

use Phalcon\Mvc\Model\Transaction\Failed as TxFailed;
use Phalcon\Mvc\Model\Transaction\Manager as TxManager;

try {
    // Create a transaction manager
    $manager = new TxManager();

    // Request a transaction
    $transaction = $manager--->get();

    $robot = new Robots();

    $robot-&gt;setTransaction($transaction);

    $robot-&gt;name       = 'WALL·E';
    $robot-&gt;created_at = date('Y-m-d');

    if ($robot-&gt;save() === false) {
        $transaction-&gt;rollback(
            'Cannot save robot'
        );
    }

    $robotPart = new RobotParts();

    $robotPart-&gt;setTransaction($transaction);

    $robotPart-&gt;robots_id = $robot-&gt;id;
    $robotPart-&gt;type      = 'head';

    if ($robotPart-&gt;save() === false) {
        $transaction-&gt;rollback(
            'Cannot save robot part'
        );
    }

    // Everything's gone fine, let's commit the transaction
    $transaction-&gt;commit();
} catch (TxFailed $e) {
    echo 'Failed, reason: ', $e-&gt;getMessage();
}

事务可用于以一致的方式删除许多记录:

<!--?php

use Phalcon\Mvc\Model\Transaction\Failed as TxFailed;
use Phalcon\Mvc\Model\Transaction\Manager as TxManager;

try {
    // Create a transaction manager
    $manager = new TxManager();

    // Request a transaction
    $transaction = $manager--->get();

    // Get the robots to be deleted
    $robots = Robots::find(
        "type = 'mechanical'"
    );

    foreach ($robots as $robot) {
        $robot-&gt;setTransaction($transaction);

        // Something's gone wrong, we should rollback the transaction
        if ($robot-&gt;delete() === false) {
            $messages = $robot-&gt;getMessages();

            foreach ($messages as $message) {
                $transaction-&gt;rollback(
                    $message-&gt;getMessage()
                );
            }
        }
    }

    // Everything's gone fine, let's commit the transaction
    $transaction-&gt;commit();

    echo 'Robots were deleted successfully!';
} catch (TxFailed $e) {
    echo 'Failed, reason: ', $e-&gt;getMessage();
}

无论在何处检索事务对象,都重用事务。仅在执行commit()rollback()时才会生成新事务。您可以使用服务容器为整个应用程序创建全局事务管理器:

<!--?php

use Phalcon\Mvc\Model\Transaction\Manager as TransactionManager;

$di--->setShared(
    'transactions',
    function () {
        return new TransactionManager();
    }
);

然后从控制器或视图访问它:

<!--?php

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function saveAction()
    {
        // Obtain the TransactionsManager from the services container
        $manager = $this--->di-&gt;getTransactions();

        // Or
        $manager = $this-&gt;transactions;

        // Request a transaction
        $transaction = $manager-&gt;get();

        // ...
    }
}

当事务处于激活状态时,事务管理器将始终在整个应用程序中返回相同的事务。

';