gpt4 book ai didi

php - 我应该怎么做才能使 MySQL 事务在我的代码中工作?

转载 作者:行者123 更新时间:2023-11-29 04:42:10 25 4
gpt4 key购买 nike

无论交易中的所有查询是否都未成功执行,我的查询都有效。

$this->mysqli->autocommit(FALSE);

$query = $this->mysqli->real_escape_string("INSERT INTO `product` (`name`, `price`) VALUES (?,?)");
$prod = $this->mysqli->prepare($query);
$prod->bind_param("ss", $name,$price);
$prod->execute();

$query = $this->mysqli->real_escape_string("INSERT INTO `member` (`user`, `address`) VALUES (?,?)");
$prod = $this->mysqli->prepare($query);
$prod->bind_param("ss", $user,$address);
$prod->execute();

$query = $this->mysqli->real_escape_string(" SOME BAD WRITTEN QUERY") ;
$prod = $this->mysqli->prepare($query);
$prod->execute();


if (!$this->mysqli->commit())
{
print("\nTransaction commit failed\n");
$this->mysqli->rollback();
}
$this->mysqli->autocommit(TRUE);

此代码正在运行并插入前两个查询,当然在第三个查询时中断。

但事务不起作用,无论它会插入每个有效的查询,我只想在所有三个查询都正确完成时插入。

我使用 INNODB 引擎和 PHP 5.5

最佳答案

当事务在 autocommit 被禁用后隐式启动时,MySQL 不会在内部跟踪您执行的语句的成功状态。那是作为程序员的工作。因此,即使 SOME BAD WRITTEN QUERY 失败,前两个成功并且可以提交。

您必须相应地测试每个和 commit()rollback() 是否成功:

注意:您应该对 SQL 语句调用 real_escape_string()。它有潜在的危害,并且对于准备好的语句字符串绝对不是必需的。

$this->mysqli->autocommit(FALSE);

$query = "INSERT INTO `product` (`name`, `price`) VALUES (?,?)";
$prod = $this->mysqli->prepare($query);
$prod->bind_param("ss", $name,$price);

// Store success/fail in a variable (returns TRUE on success)
$success1 = $prod->execute();

$query = "INSERT INTO `member` (`user`, `address`) VALUES (?,?)";
$prod = $this->mysqli->prepare($query);
$prod->bind_param("ss", $user,$address);

// Store success/fail in a variable (returns TRUE on success)
$success2 = $prod->execute();

$query = " SOME BAD WRITTEN QUERY";
$prod = $this->mysqli->prepare($query);

// Store success/fail in a variable (returns FALSE on failure)
$success3 = $prod->execute();

// Now check if all 3 succeeded and commit() if they did
if ($success1 && $success2 && $success3)
{
$this->mysqli->commit();
}
// Or rollback() if they didn't
else
{
print("\nTransaction commit failed\n");
$this->mysqli->rollback();
}
$this->mysqli->autocommit(TRUE);

最后一点。如果您只是为单个事务禁用 autocommit 然后重新启用它,请考虑只保留 autocommit enabled 并明确开始和结束事务。不要调用 $this->mysqli->autocommit(false) 和以后的 $this->mysqli->autocommit(true);,只需调用

// Don't disable autocommit
// Start it...
$this->mysqli->begin_transaction();
// Do your 3 queries as above and test for success
// Then commit or rollback
$this->mysqli->commit();
// (or rollback)
// Now, no need to re-enable auto-commit

如果您的应用程序将使用大量事务,那么一定要禁用autocommit。您需要在每次操作后显式地commit(),但我不会为了在一次交易后重新启用它而禁用它。

关于 DDL 语句的注意事项 - MySQL 无法回滚 DDL 语句,我相信调用一个中间事务将导致提交所有先前的语句,即使您尚未显式调用 commit()。因此,如果您从代码中发出 CREATE,ALTER,DROP 语句,请注意这一点。它们不能用于交易。

关于php - 我应该怎么做才能使 MySQL 事务在我的代码中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26207484/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com