PHP MySQL事务
简介:在本教程中,您将学习如何在PHP中处理MySQL事务以确保数据库的数据完整性。
事务是一组相互依赖的SQL语句,需要以全有或全无模式执行。
如果所有SQL语句成功执行,则事务成功。
任何语句失败都会触发系统回滚到原始状态,以避免数据不一致。
交易的经典示例是从一个银行帐户到另一个银行帐户的汇款交易。
它需要三个步骤:
检查已转帐帐户的余额,以查看该金额是否足以进行转帐。
如果金额足够,请从转帐的余额中扣除该金额。
将转帐金额添加到收款帐户的余额中。
如果第二步出错,则第三步不应继续。
另外,如果在第三步中发生错误,则第二步必须逆转。
如果发生故障,两个银行帐户的金额均保持不变,或者如果交易成功完成,则可以正确调整。
PHP中的MySQL事务
当您使用PDO创建与支持事务的数据库的连接时,将设置自动提交模式。
这意味着您发出的每个查询都包装在一个隐式事务中。
请注意,并非MySQL中的所有存储引擎都支持事务,例如MyISAM不支持事务,但是InnoDB支持。
要在PHP中处理MySQL事务,请使用以下步骤:
通过调用PDO对象的beginTransaction()方法来启动事务。
将SQL语句和commit()方法调用放在try块中。
通过调用PDO对象的rollBack()方法在catch块中回滚事务。
PHP MySQL交易示例
我们将创建一个名为accounts的表,以演示两个银行帐户之间的资金转移。
首先,执行以下语句创建accounts表:
CREATE TABLE accounts (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR (50) NOT NULL,
amount DECIMAL (19, 4) NOT NULL
);
第二,在accounts表中插入两行:
INSERT INTO accounts(name,amount)
VALUES('John',25000),
('Mary',95000);
三,查询账户表:
SELECT * FROM accounts;
让我们看一下下面的TransactionDemo类:
<?php
/**
* PHP MySQL Transaction Demo
*/
class TransactionDemo {
const DB_HOST = 'localhost';
const DB_NAME = 'classicmodels';
const DB_USER = 'root';
const DB_PASSWORD = '';
/**
* Open the database connection
*/
public function __construct() {
// open database connection
$conStr = sprintf("mysql:host=%s;dbname=%s", self::DB_HOST, self::DB_NAME);
try {
$this->pdo = new PDO($conStr, self::DB_USER, self::DB_PASSWORD);
} catch (PDOException $e) {
die($e->getMessage());
}
}
/**
* PDO instance
* @var PDO
*/
private $pdo = null;
/**
* Transfer money between two accounts
* @param int $from
* @param int $to
* @param float $amount
* @return true on success or false on failure.
*/
public function transfer($from, $to, $amount) {
try {
$this->pdo->beginTransaction();
// get available amount of the transferer account
$sql = 'SELECT amount FROM accounts WHERE id=:from';
$stmt = $this->pdo->prepare($sql);
$stmt->execute(array(":from" => $from));
$availableAmount = (int) $stmt->fetchColumn();
$stmt->closeCursor();
if ($availableAmount < $amount) {
echo 'Insufficient amount to transfer';
return false;
}
// deduct from the transferred account
$sql_update_from = 'UPDATE accounts
SET amount = amount - :amount
WHERE id = :from';
$stmt = $this->pdo->prepare($sql_update_from);
$stmt->execute(array(":from" => $from, ":amount" => $amount));
$stmt->closeCursor();
// add to the receiving account
$sql_update_to = 'UPDATE accounts
SET amount = amount + :amount
WHERE id = :to';
$stmt = $this->pdo->prepare($sql_update_to);
$stmt->execute(array(":to" => $to, ":amount" => $amount));
// commit the transaction
$this->pdo->commit();
echo 'The amount has been transferred successfully';
return true;
} catch (PDOException $e) {
$this->pdo->rollBack();
die($e->getMessage());
}
}
/**
* close the database connection
*/
public function __destruct() {
// close the database connection
$this->pdo = null;
}
}
// test the transfer method
$obj = new TransactionDemo();
// transfer 30K from from account 1 to 2
$obj->transfer(1, 2, 30000);
// transfer 5K from from account 1 to 2
$obj->transfer(1, 2, 5000);
我们使用__construct()方法打开数据库连接,并使用__destruct()方法关闭数据库连接。
在transfer()方法中:
首先,我们查询转帐帐户的金额并将其与转帐金额进行比较,以检查转帐帐户的余额是否足够。
其次,在金额足够的情况下,我们从已转帐帐户中扣除转帐金额,并将其添加到接收帐户中。
第三,我们通过调用commit()方法来提交事务。
如果发生任何错误,我们在catch块中调用rollBack()方法以回滚事务。
让我们测试transfer()方法。
// transfer 30K from from account 1 to 2 $obj->transfer(1, 2, 30000);
我们从John的帐户中将3万转移到了Mary的帐户中。
我们收到以下消息:
Insufficient amount to transfer
再进行一次转移:
// transfer 5K from from account 1 to 2 $obj->transfer(1, 2, 5000);
该脚本返回以下消息:
The amount has been transferred successfully.
我们已成功在两个银行帐户之间转帐。
您可以通过以下链接下载源代码:
下载PHP MySQL事务源代码
在本教程中,我们逐步向您展示了如何在PHP中处理MySQL事务以确保数据完整性。

