繁体   English   中英

MySQL 提交和事务

[英]MySQL commit and transaction

我有一个关于 MySQL 提交和事务的问题。 我有几个执行 MySQL 查询的 PHP 语句。 我只说以下吗?

mysql_query("START TRANSACTION");
//more queries here
mysql_query("COMMIT");

这究竟会做什么? 它有什么帮助? 对于更新、删除和插入,我还发现这可以阻止其他查询读取:

mysql_query("LOCK TABLES t1 WRITE, t2 WRITE");
//more queries here
mysql_query("UNLOCK TABLES t1, t2");

这会阻止任何性质的其他查询还是仅写入/选择?

另一个问题:假设一个查询正在运行并阻止其他查询。 另一个查询尝试访问被阻止的数据 - 它发现它被阻止了。 它是如何进行的? 是不是等到数据再次解除阻塞再重新执行查询? 它是否只是失败并需要重复? 如果是这样,我该如何检查?

非常感谢!

丹尼斯

在 InnoDB 中,如果您没有更改 autocommit 的默认设置,即“on”,则不需要显式启动或结束单个查询的事务。 如果启用自动提交,InnoDB 会自动将每个 SQL 查询包含在事务中,这相当于START TRANSACTION; query; COMMIT; START TRANSACTION; query; COMMIT; .

如果您在 InnoDB 中显式使用START TRANSACTION并启用自动提交,那么在START TRANSACTION语句之后执行的任何查询要么全部执行,要么全部失败。 这在银行环境中很有用,例如:如果我将 500 美元转入您的银行帐户,则只有从我的银行余额中减去该金额并添加到您的余额中,该操作才会成功。 所以在这种情况下,你会运行类似

START TRANSACTION;
UPDATE customers SET balance = balance - 500 WHERE customer = 'Daan';
UPDATE customers SET balance = balance + 500 WHERE customer = 'Dennis';
COMMIT;

这确保了两个查询都会成功运行,或者没有,但不仅仅是一个。 这篇文章有更多关于何时应该使用事务的内容。

在 InnoDB 中,您很少需要锁定整个表; InnoDB 与 MyISAM 不同,支持行级锁定。 这意味着客户端不必锁定整个表,从而迫使其他客户端等待。 客户端应该只锁定他们实际需要的行,允许其他客户端继续访问他们需要的行。

您可以在此处阅读有关 InnoDB 事务的更多信息。 您关于死锁的问题在文档的14.2.8.814.2.8.9节中得到了解答。 如果查询失败,您的 MySQL 驱动程序将返回一条错误消息,指出原因; 如果需要,您的应用程序应重新发出查询。

最后,在您的示例代码中,您使用了mysql_query 如果您正在编写新代码,请停止为 PHP 使用旧的、缓慢的和已弃用的mysql_库,而改用mysqli_或 PDO :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM