PDO
在线手册:中文  英文

PDO::rollBack

(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0)

PDO::rollBack 回滚一个事务

说明

bool PDO::rollBack ( void )

回滚由 PDO::beginTransaction() 发起的当前事务。如果没有事务激活,将抛出一个 PDOException 异常。

如果数据库被设置成自动提交模式,此函数(方法)在回滚事务之后将恢复自动提交模式。

包括 MySQL 在内的一些数据库, 当在一个事务内有类似删除或创建数据表等 DLL 语句时,会自动导致一个隐式地提交。隐式地提交将无法回滚此事务范围内的任何更改。

返回值

成功时返回 TRUE, 或者在失败时返回 FALSE

范例

Example #1 回滚一个事务

下面例子在回滚更改之前开始一个事务并发出两条修改数据库的语句。但在 MySQL 中,DROP TABLE 语句自动提交事务,因此在此事务内的任何更改都不会被回滚。

<?php
/* 开始一个事务,关闭自动提交 */
$dbh->beginTransaction();

/* 更改数据库架构和数据  */
$sth $dbh->exec("DROP TABLE fruit");
$sth $dbh->exec("UPDATE dessert
    SET name = 'hamburger'"
);

/*  识别错误且回滚更改  */
$dbh->rollBack();

/*  此时数据库连接恢复到自动提交模式  */
?>

参见


PDO
在线手册:中文  英文

用户评论:

Petros Giakouvakis (2010-11-10 13:30:26)

Should anyone reading this be slightly panicked because they just discovered that their MySQL tables are MyIsam and not InnoDb, don't worry... You can very easily change the storage engine using the following query:
ALTER TABLE your_table_name ENGINE = innodb;

brian at diamondsea dot com (2008-03-25 07:19:39)

Here is a way of testing that your transaction has started when using MySQL's InnoDB tables.  It will fail if you are using MySQL's MyISAM tables, which do not support transactions but will also not return an error when using them.

<?
// Begin the transaction
$dbh->beginTransaction();

// To verify that a transaction has started, try to create an (illegal for InnoDB) nested transaction.
//    If it works, the first transaction did not start correctly or is unsupported (such as on MyISAM tables)
try {
    $dbh->beginTransaction();
    die('Cancelling, Transaction was not properly started');
} catch (PDOException $e) {
    print "Transaction is running (because trying another one failed)\n";
}
?>

JonasJ (2008-01-08 13:59:50)

Just a quick (and perhaps obvious) note for MySQL users;
Don't scratch your head if it isn't working if you are using a MyISAM table to test the rollbacks with.
Both rollBack() and beginTransaction() will return TRUE but the rollBack will not happen.
Convert the table to InnoDB and run the test again.

linfo2003 at libero dot it (2007-05-29 19:07:35)

Since "It is an error to call this method if no transaction is active", it could be useful (even if not indispensable) to have a method which returns true if a transaction is active.
try {
$dbh->beginTransaction();
...
} catch (PDOException $e) {
if ($dbh->isTransactionActive()) // this function does NOT exist
$dbh->rollBack();
...
}
In the meanwhile, I'm using this code:
...
} catch (PDOException $e) {
try { $dbh->rollBack(); } catch (Exception $e2) {}
...
}
It's not so chic, but it works fine.

emalinks at gmail dot com (2007-04-14 13:09:56)

<?php
//run this on your latest PHP let me know if it doesn't fail
//to test this program u must run it twice at the same time in ie. two terminals
//this program suposedly creates a new dbase with table name NodeNames and one field in it named NodeName
//it then begins a transaction then attempts to read an element 'zTest' of field 'NodeName' which obv. doesn't exist, ignoring the returned errors
//then it writes it(since it wasn't there)
//then decides to rollBack the transaction and eventually try a new one
//because rollBack doesn't really work(apparently) for some unknown reason, beginTransaction fails saying 'There is already an active transaction'
$db = new PDO('sqlite:demlinks6.3sql',''/*user*/,''/*pwd*/);

$db->exec('CREATE TABLE \'NodeNames\' ("NodeName" VARCHAR(10));');

$db->beginTransaction();

$getter="zTest";
$pgn $db->prepare('SELECT * FROM \'NodeNames\' WHERE "NodeName" = :node13');
$pgn->bindParam(":node13"$getterPDO::PARAM_STR);
//read
$pgn->execute();//execute above SELECT
$ar=$pgn->FetchAll();//get array of results

$writter="zTest";
$pnn=$db->prepare('INSERT INTO \'NodeNames\' ("NodeName") VALUES (:node14)');
$pnn->bindParam(":node14"$writterPDO::PARAM_STR);
//write
$pnn->execute();//write it!

echo "waiting...";
usleep(2000000);
echo 
"done\n";
$db->rollBack();//this doesn't do it's job
$db->beginTransaction();//here it fails, when running this program twice at the same time; 'There is already an active transaction'
//unreachable:
$db->commit();
?>

易百教程