【发布时间】:2013-07-13 01:30:30
【问题描述】:
我已经阅读了在线 php 手册,但我仍然不确定这两个函数的工作方式:mysqli::commit 和 mysqli::rollback。
我要做的第一件事是:
$mysqli->autocommit(FALSE);
然后我做了一些查询:
$mysqli->query("...");
$mysqli->query("...");
$mysqli->query("...");
然后我提交由这 3 个查询组成的事务:
$mysqli->commit();
但是在这些查询之一不起作用的不幸情况下,是所有 3 个查询都被取消还是我必须自己调用回滚?我希望所有 3 个查询都是原子的,并且只被视为一个查询。如果一个查询失败,那么所有 3 个都应该失败并且没有任何效果。
我问这个是因为在我在手册页上看到的 cmets 中:http://php.net/manual/en/mysqli.commit.php 如果其中一个查询失败,用户 Lorenzo 会调用回滚。
如果 3 个查询是原子的,那么回滚有什么好处?我不明白。
编辑:这是我怀疑的代码示例:
<?php
$all_query_ok=true; // our control variable
$mysqli->autocommit(false);
//we make 4 inserts, the last one generates an error
//if at least one query returns an error we change our control variable
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") ? null : $all_query_ok=false;
$mysqli->query("INSERT INTO myCity (id) VALUES (200)") ? null : $all_query_ok=false;
$mysqli->query("INSERT INTO myCity (id) VALUES (300)") ? null : $all_query_ok=false;
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") ? null : $all_query_ok=false; //duplicated PRIMARY KEY VALUE
//now let's test our control variable
$all_query_ok ? $mysqli->commit() : $mysqli->rollback();
$mysqli->close();
?>
我认为这段代码是错误的,因为如果任何查询失败并且$all_query_ok==false,那么您不需要进行回滚,因为事务没有被处理。我说的对吗?
【问题讨论】:
-
开始工作块在哪里?你知道什么是自动提交吗?
-
如果您将 sql 语句包装在
BEGIN TRANSACTIONEND块中,则此方法有效。因此,如果您的任何语句在事务块内失败,它会回滚事务。 -
@N.B.我想我知道什么是自动提交:如果它打开了,那么我调用的每个查询都将立即由数据库处理,如果它被关闭,那么只有在 $mysqli->commit(); 时查询才会发送到数据库;被调用。
-
@Ariel - 自动提交是 InnoDB 的工作模式。
commit除其他外,要求操作系统验证永久存储设备(在本例中为硬盘驱动器)是否已将信息写下并且它不在任何内存缓冲区中。这是一个昂贵的信息/动作,它使用了 1 个输入输出操作。当自动提交打开时,发送到数据库的每个查询将使用 1 个 I/O 抛出异常/如果失败则引发错误。关闭自动提交对事务来说基本上没有意义。您需要一个begin work块,而不是关闭自动提交。 -
@N.B.:
BEGIN WORK(以及它推荐的标准化替代方案START TRANSACTION)只是为一个事务隐式关闭自动提交。即使在事务结束后,显式关闭自动提交也会使其关闭。就这个问题而言,差别不大。
标签: php mysql mysqli commit rollback