首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ACID事务中的行锁定

ACID事务中的行锁定
EN

Database Administration用户
提问于 2014-02-12 05:44:22
回答 2查看 2.3K关注 0票数 2

我有一项类似于以下(伪)的金融交易:

代码语言:javascript
复制
begin
    select record for update
    update record(same record as selected)
    insert another record into another table
commit

如果我在事务中调用SELECT ... FOR UPDATE,那么只有当事务提交时,才会释放特定行的锁吗?

EN

回答 2

Database Administration用户

回答已采纳

发布于 2014-02-12 06:53:25

根据MySQL 5.0认证研究指南 418页第3段

以下命令可以破坏事务

  • ALTER TABLE
  • BEGIN
  • CREATE INDEX
  • DROP DATABASE
  • DROP INDEX
  • DROP TABLE
  • RENAME TABLE
  • TRUNCATE TABLE
  • LOCK TABLES
  • UNLOCK TABLES
  • SET AUTOCOMMIT = 1
  • START TRANSACTION

只要在事务中不执行任何这些命令,事务就应该是稳定的。实际上,SELECT FOR UPDATE是如此强大,以至于行锁入侵了索引和数据。它甚至可能引发可能的InnoDB死锁。我曾经在这篇文章里写过:选择“更新”使索引列出现错误

只要您保持事务简短和甜蜜,SELECT FOR UPDATE就不会是一个问题。如果要保护事务不受间歇性或意外死锁的影响,MySQL 5.6现在有以下内容:

  • START TRANSACTION READ WRITE;
  • START TRANSACTION READ ONLY;

您应该使用这样的选项启动事务。为什么?

根据那个MySQL文档的说法:

读、写和只读修饰符设置事务访问模式。它们允许或禁止对事务中使用的表进行更改。只读限制阻止事务修改或锁定对其他事务可见的事务性表和非事务性表;事务仍然可以修改或锁定临时表。这些修饰符可在MySQL 5.6.5中使用。

你最后的评论是

因此,我是否可以以另一种方式锁定事务中的行,以便进行更新?

您还可以运行选择。锁定共享模式。文件上说

  • 选择。在共享模式中锁定任何读取的行,都会设置共享模式锁。其他会话可以读取行,但在事务提交之前不能修改它们。如果这些行中的任何一行被尚未提交的另一个事务更改,则您的查询将一直等到该事务结束,然后使用最新的值。
  • 对于索引记录搜索遭遇,选择..。对于UPDATE锁定行和任何关联的索引项,就像您为这些行发出了UPDATE语句一样。其他事务被阻止更新这些行,执行选择.锁定共享模式,或读取某些事务隔离级别中的数据。一致读取忽略在read视图中存在的记录上设置的任何锁。(记录的旧版本无法锁定;它们是通过在记录的内存副本上应用撤消日志来重构的。)

尽管有可能,但要保持交易时间短。否则,您可能会增加死锁的可能性。

更新2014-02-13 21:57 EST

为了澄清任何误解,请从MySQL文档中注意这一点.

在提交或回滚事务时,由锁在共享模式下设置的所有锁和用于更新查询的所有锁都会被释放。

因此,如果执行SELECT .在事务内锁定共享模式,这些行将保持锁定状态,直到事务提交或回滚。

票数 5
EN

Database Administration用户

发布于 2016-09-09 08:56:30

另外,如果异常处理程序不在循环,并且事务范围与in循环一起,即使mysql在异常情况下中断事务,最好声明异常处理程序(如果有相同范围的事务被声明)。

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

https://dba.stackexchange.com/questions/58709

复制
相关文章

相似问题

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