ZetCode

在PostgreSQL中使用PHP进行事务处理

最后修改于 2020 年 7 月 6 日

在本章中,我们将使用事务。首先,我们提供一些基本定义。然后,我们将提供一个使用事务的示例程序。

一个事务是对一个或多个数据库中数据的原子单元操作。事务中的SQL语句要么全部提交到数据库,要么全部回滚。SQL语句被放入事务中以确保数据安全性和完整性。

在PostgreSQL PHP中,每个SQL语句在执行后都会提交到数据库。这并非适用于所有语言绑定。例如,在Python的psycopg2模块中,默认情况下,所有更改都必须使用commit方法显式提交。

在直接SQL中,事务以BEGIN TRANSACTION语句开始,以END TRANSACTIONCOMMIT语句结束。在PostgreSQL中,这些语句是BEGINCOMMIT。在某些驱动程序中,这些语句被省略。它们由驱动程序处理。在PHP中,没有这样的方法,我们必须使用直接SQL。(在PHP PDO中,有这样的方法。)

<?php 

$host = "localhost"; 
$user = "user12"; 
$pass = "34klq*"; 
$db = "testdb"; 

$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
    or die ("Could not connect to server\n"); 

pg_query("BEGIN") or die("Could not start transaction\n");

$res1 = pg_query("DELETE FROM cars WHERE id IN (1, 9)");
$res2 = pg_query("INSERT INTO cars VALUES (1, 'BMW', 36000), (9, 'Audi', 52642)");

if ($res1 and $res2) {
    echo "Commiting transaction\n";
    pg_query("COMMIT") or die("Transaction commit failed\n");
} else {
    echo "Rolling back transaction\n";
    pg_query("ROLLBACK") or die("Transaction rollback failed\n");;
}

pg_close($con); 

?>

我们有一个cars表。我们想将第一行与最后一行交换。我们分两步完成。首先,我们删除这两行。然后,我们插入它们,并交换它们的id。这两个操作需要放在一个事务中。如果第一步成功而第二步失败,数据将被破坏。因此,我们需要要么全部完成,要么什么都不做。

pg_query("BEGIN") or die("Could not start transaction\n");

我们通过发出BEGIN语句开始一个新的事务。

$res1 = pg_query("DELETE FROM cars WHERE id IN (1, 9)");
$res2 = pg_query("INSERT INTO cars VALUES (1, 'BMW', 36000), (9, 'Audi', 52642)");

以下是修改我们表的两个SQL语句。两个pg_query函数都返回true或false布尔值,指示SQL命令是否失败。

if ($res1 and $res2) {
    echo "Commiting transaction\n";
    pg_query("COMMIT") or die("Transaction commit failed\n");
} else {
    echo "Rolling back transaction\n";
    pg_query("ROLLBACK") or die("Transaction rollback failed\n");;
}

如果两个函数调用都返回true,我们使用COMMIT语句提交事务。否则,我们使用ROLLBACK语句回滚更改。

$ php transaction.php
Commiting transaction

testdb=# SELECT * FROM cars ORDER BY id;
 id |    name    | price  
----+------------+--------
  1 | BMW        |  36000
  2 | Mercedes   |  57127
  3 | Skoda      |   9000
  4 | Volvo      |  29000
  5 | Bentley    | 350000
  6 | Citroen    |  21000
  7 | Hummer     |  41400
  8 | Volkswagen |  21606
  9 | Audi       |  52642
(9 rows)

这些行已成功交换。

在本部分PostgreSQL PHP教程中,我们提到了事务。