PHP:PDO 事务示例

在本指南中,我们将向您展示如何将事务与 PHP 的 PDO 对象一起使用。

对于那些不知道的人,数据库事务代表一个“块”或一个“单元”工作。

在大多数情况下,这个工作“单元”将由多个查询组成,这些查询以某种方式相互关联。

在某些情况下,您可能希望确保在将更改提交到数据库之前成功执行所有查询。

对于这个例子,我们将创建一个模拟 PHP 应用程序,为用户帐户添加资金。

在这种情况下,我们有两个查询。第一个将支付记录插入一个名为“payments”的表中。第二个将更新用户帐户的余额。

/**
 * Connect to MySQL and instantiate the PDO object.
 * Set the error mode to throw exceptions and disable emulated prepared statements.
 */
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '', array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false
));


//We are going to assume that the user with ID #1 has paid 10.50.
$userId = 1;
$paymentAmount = 10.50;


//We will need to wrap our queries inside a TRY / CATCH block.
//That way, we can rollback the transaction if a query fails and a PDO exception occurs.
try{

    //We start our transaction.
    $pdo->beginTransaction();


    //Query 1: Attempt to insert the payment record into our database.
    $sql = "INSERT INTO payments (user_id, amount) VALUES (?, ?)";
    $stmt = $pdo->prepare($sql);
    $stmt->execute(array(
            $userId, 
            $paymentAmount,
        )
    );
    
    //Query 2: Attempt to update the user's profile.
    $sql = "UPDATE users SET credit = credit + ? WHERE id = ?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute(array(
            $paymentAmount, 
            $userId
        )
    );
    
    //We've got this far without an exception, so commit the changes.
    $pdo->commit();
    
} 
//Our catch block will handle any exceptions that are thrown.
catch(Exception $e){
    //An exception has occured, which means that one of our database queries
    //failed.
    //Print out the error message.
    echo $e->getMessage();
    //Rollback the transaction.
    $pdo->rollBack();
}

在此示例中,我们确保在提交更改之前所有查询都成功。

换句话说,如果第二个查询无法更新用户的信用余额,我们不想在支付表中插入记录。

我们的 PDO 事务代码的解释。

上面的PHP代码的一步一步的解释:

  1. 首先,我们使用 PDO 对象连接到 MySQL 。我们将错误模式设置为 PDO::ERRMODE_EXCEPTION以便 PHP 在发生错误时抛出 PDO 异常。我们还通过将PDO::ATTR_EMULATE_PREPARES设置为 false 来禁用模拟的预处理语句。
  2. 为了这个例子,我们将用户 ID 设置为 1,支付金额设置为 10.50。
  3. 我们首先打开Try / Catch块。我们所有的查询都将发生在这个“尝试块”内,以便我们可以捕获任何可能发生的异常。
  4. 我们通过调用beginTransaction函数在 Try 块中开始我们的事务。当我们调用这个函数时,它将禁用 MySQL 的自动提交模式。这意味着 MySQL 在我们告诉它之前不会提交任何更改。
  5. 之后,我们尝试将付款插入到付款表中。
  6. 然后,我们使用新的信用计数更新用户的帐户。
  7. 最后,我们通过调用commit函数来提交事务。

如果我们的查询之一失败,则会抛出 PDO 异常

如果发生这种情况,我们的 catch 块内的代码将执行。

在那个阶段,MySQL 将中止事务并回滚任何更改。

交易条款。

一些关键术语的快速解释。

  • 开始事务:事务从禁用 MySQL 的默认自动提交性质开始。例如,如果您运行 INSERT 查询,MySQL 将不会提交更改。相反,它将“保留”查询,直到您手动提交它。
  • 提交:当您提交事务时,您基本上是在告诉 MySQL 它应该继续并保存任何更改。这是“一切顺利”的另一种说法。您现在可以保存这些更改。”
  • Rollback:当你执行回滚时,你是在告诉 MySQL 中止事务并丢弃任何更改。通常,只有在查询失败时才会发生回滚。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值