【问题标题】:MySQL Row level locksMySQL 行级锁
【发布时间】:2017-02-01 13:39:42
【问题描述】:

我不确定行级锁是如何工作的,但这是我的问题 我有一个表 T(id int,balance int)(engine = InnoDB),我想锁定 ID = 1 的行,所以我开始这样的事务:

start transaction ; 
select * from T where ID = 1 FOR UPDATE ; 

在发送提交之前,我想尝试一下这些行是否真的被锁定了。所以我开始了另一个会话并输入了:

UPDATE T set balance = balance  + 100 where ID = 1 ;

在这里我清楚地看到我在等待锁定(30 秒后超时)。

但是当我输入时:

UPDATE T set balance = balance  + 8500 where ID = 2 ;

我也在等待锁,那我怎样才能只锁定 ID = 1 行而不是整个表呢?

【问题讨论】:

  • ID 列上是否有索引?
  • 不,这很重要吗????
  • 是的。它锁定它必须读取以执行查询的所有行。如果该列没有被索引,它必须读取表中的所有行以找到ID = 1 所在的行,并在读取时锁定它们。当列被索引时,不需要扫描表(锁实际上是在索引中实现的)。

标签: mysql database transactions innodb locks


【解决方案1】:

您需要在id 列上添加索引,以确保获得行级锁。 SELECT ... FOR UPDATE 锁定为执行查询而读取的所有行,而不仅仅是实际选择的行。如果没有索引,它必须执行全表扫描,因此每一行都会被锁定。

有了索引,它只是在那个索引条目中加了一个锁,它不需要读取任何其他行,所以不会锁定其他行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多