php - MySQL 提交和事务

标签 php mysql transactions commit

我有一个关于 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 中,如果您没有更改自动提交的默认设置(“开”),则不需要显式地开始或结束单个查询的事务。如果打开自动提交,InnoDB 会自动将每个 SQL 查询包含在一个事务中,这相当于 START TRANSACTION;询问;提交;

如果您在 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 中,您很少需要锁定整个表; InnoDB 与 MyISAM 不同,它支持行级锁定。这意味着客户端不必锁定整个表,迫使其他客户端等待。客户端应该只锁定他们实际需要的行,允许其他客户端继续访问他们需要的行。

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

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

关于php - MySQL 提交和事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10585218/

相关文章:

MYSQL - 根据ID插入多行连接结果

mysql - 学习sql建表报错

php - Composer 完成执行后退出批处理文件

php - MySql select by score desc - 当有多个总分时....奇怪

PHP PCRE 允许字符串中的嵌套模式(递归)

mysql - 带有 EXISTS 的子查询

postgresql - Postgres 事务似乎无缘无故采用 AccessExclusiveLock

javascript - Marklogic xdmp.rollback() : Cannot read property 'result' of null

sqlite - Sqlite事务是否超时?

php - 从Symfony2捕获ContextErrorException