首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL提交和事务

MySQL提交和事务
EN

Stack Overflow用户
提问于 2012-05-14 22:22:22
回答 1查看 22.2K关注 0票数 10

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

代码语言:javascript
运行
复制
mysql_query("START TRANSACTION");
//more queries here
mysql_query("COMMIT");

这到底能做什么呢?它有什么帮助呢?对于更新、删除和插入,我也发现这会阻止其他查询读取:

代码语言:javascript
运行
复制
mysql_query("LOCK TABLES t1 WRITE, t2 WRITE");
//more queries here
mysql_query("UNLOCK TABLES t1, t2");

这是否会阻止其他任何性质的查询,或者只是写/选择?

另一个问题:假设一个查询正在运行,并阻塞了其他查询。另一个查询试图访问被阻塞的数据,但它发现它被阻塞了。它是如何进行的?它会等到数据再次被解锁后再重新执行查询吗?它只是失败了,需要重复吗?如果是这样的话,我怎么检查?

非常感谢!

丹尼斯

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-15 01:50:59

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

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

代码语言:javascript
运行
复制
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 transactions here的更多信息。您关于死锁的问题在文档的14.2.8.814.2.8.9部分中得到了解答。如果查询失败,您的MySQL驱动程序将返回一条错误消息,指出原因;然后,如果需要,您的应用程序应该重新发出查询。

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

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10585218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档