【问题标题】:MySQL commit and transactionMySQL 提交和事务
【发布时间】:2012-05-22 01:10:20
【问题描述】:

我有一个关于 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 还是 MyISAM 表?

标签: php mysql transactions commit


【解决方案1】:

在 InnoDB 中,如果您没有更改 autocommit 的默认设置,即“on”,则无需显式启动或结束单个查询的事务。如果启用自动提交,InnoDB 会自动将每个 SQL 查询包含在事务中,这相当于 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;

这确保了两个查询都将成功运行,或者没有一个,但不仅仅是一个。 This post 有更多关于何时应该使用事务的信息。

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

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

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

【讨论】:

  • 太棒了,谢谢!那么 InnoDB 会自动只锁定行吗?以及如何检查我的表是否有自动提交?以及如何在其上设置索引(我正在使用 phpmyadmin)
  • 您可以发出SHOW VARIABLES LIKE 'autocommit' 查询,或在phpMyAdmin 主页上单击variables。通过转到相应的数据库和表,单击structure 并使用您在此处看到的表格创建索引来创建索引。或者您可以发出 SQL 语句,例如ALTER TABLE table ADD INDEX (field)。我不确定您所说的“InnoBD 是否自动仅锁定行”是什么意思 - 如果您是这个意思,它肯定永远不会自动锁定整个表 :)
  • 自动提交已开启 :) 主键是否始终用作索引?我的表中有主键并想添加一个索引,但它说它只能与主键相同...
  • 是的,主键用作索引:)
  • 来自MySQL documentation:要隐式为单个语句系列禁用自动提交模式,请使用 START TRANSACTION 语句。使用 START TRANSACTION,自动提交保持禁用状态,直到您使用 COMMIT 或 ROLLBACK 结束事务。然后自动提交模式恢复到之前的状态。
猜你喜欢
  • 2012-12-24
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2023-03-27
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多