PHP和MySQL:实现事务的简单代码-提交和回滚

7

我的平台:

PHP和MySQL

我的情况:

我正在尝试在我的代码中实现事务。我尝试按照示例进行操作,但并没有什么帮助。我运行了3个查询,并希望编写一个事务,以便如果任何一个查询失败,整个事务都应该回滚。我非常希望能够使用一个简单、高效且非面向对象的PHP代码来实现这个目标。谢谢您提前的帮助。

我的PHP代码:

//db_res calls a custom function that performs a mysql_query on the query
$res1 = db_res("SELECT c1, c2 FROM t1 WHERE c5 = 3");
$res2 = db_res("UPDATE t2 SET c1 = 5 WHERE c2 = 10");
$res3 = db_res("DELETE FROM t3 WHERE c1 = 20");

if( $res1 && $res2 && $res3 )
{
 //commit --- but how?
}
else
{
 //rollback --- but how?
}

请查看此链接:http://dev.mysql.com/doc/refman/5.0/en/commit.html。这应该会指引您朝正确的方向前进。 - Shadrack Orina
1
在https://dev59.com/GHE85IYBdhLWcg3wkkjK上提供了一个简单而优秀的答案/示例(try catch),必须阅读,以清晰简明的术语准确地展示了该怎么做。 - tony gil
2个回答

19

您不需要使用mysqli。您可以将事务命令作为查询发出。

因此,以您的示例为例:

mysql_query("start transaction;");

//db_res calls a custom function that performs a mysql_query on the query
$res1 = db_res("SELECT c1, c2 FROM t1 WHERE c5 = 3");
$res2 = db_res("UPDATE t2 SET c1 = 5 WHERE c2 = 10");
$res3 = db_res("DELETE FROM t3 WHERE c1 = 20");

if( $res1 && $res2 && $res3 )
{
  mysql_query("commit;");
}
else
{
  mysql_query("rollback;");
}

顺便说一句,如果你正在考虑升级到mysqli,请不要这么做。相反,升级到PDO,它更加合理。


我认为你的意思是mysql_query("start transaction");或者mysql_query("begin");。 - Rooster242
是的,我把这两个搞混了...会修复的。 - rjmunro
MySQL 不安全,尝试使用 mysqli 或 PDO。 - Asuquo12
@Asuquo12 是的,绝对要使用PDO。我甚至在我的回答末尾也这么说了。但是,如果你正在使用一些遗留的内部mysql东西,你可以像我上面展示的那样进行事务处理,而无需升级。 - rjmunro

9

您需要使用 mysqli扩展来使用此功能。

参见:autocommit(), commit(), 和 rollback()

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

/* disable autocommit */
mysqli_autocommit($link, FALSE);

mysqli_query($link, "CREATE TABLE myCity LIKE City");
mysqli_query($link, "ALTER TABLE myCity Type=InnoDB");
mysqli_query($link, "INSERT INTO myCity SELECT * FROM City LIMIT 50");

/* commit insert */
mysqli_commit($link);

/* delete all rows */
mysqli_query($link, "DELETE FROM myCity");

if ($result = mysqli_query($link, "SELECT COUNT(*) FROM myCity")) {
    $row = mysqli_fetch_row($result);
    printf("%d rows in table myCity.\n", $row[0]);
    /* Free result */
    mysqli_free_result($result);
}

/* Rollback */
mysqli_rollback($link);

if ($result = mysqli_query($link, "SELECT COUNT(*) FROM myCity")) {
    $row = mysqli_fetch_row($result);
    printf("%d rows in table myCity (after rollback).\n", $row[0]);
    /* Free result */
    mysqli_free_result($result);
}

/* Drop table myCity */
mysqli_query($link, "DROP TABLE myCity");

mysqli_close($link);
?>

@John 谢谢您的回复。我已经使用mysql_query构建了超过85%的应用程序。如果我必须使用mysqli,我认为我需要修改我的应用程序并从头开始重新设计它。是否有任何可能以任何方式使用mysql_query来完成它?我不确定此时是否可以切换到mysqli,因此非常感谢提供替代解决方案。期待您的回复。 - Devner
2
很遗憾,mysql_*函数无法访问MySQL 4及更高版本提供的高级功能,如事务和存储过程。您不需要返回并更改每个对MySQL的调用以使用mysqli。只需更改实际需要使用它的页面即可。 - John Conde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接