MySQL 行级锁
MySQL Row level locks
我不确定行级锁是如何工作的,但这是我的问题
我有一个 table 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 行而不是完全锁定 table?
您需要在id
列上添加索引以确保您获得行级锁。 SELECT ... FOR UPDATE
锁定执行查询时读取的所有行,而不仅仅是实际选择的行。没有索引,它必须执行完整的 table 扫描,因此每一行都会被锁定。
有了索引,它只是在该索引条目中加锁,它不必读取任何其他行,因此不会锁定其他行。
我不确定行级锁是如何工作的,但这是我的问题 我有一个 table 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 行而不是完全锁定 table?
您需要在id
列上添加索引以确保您获得行级锁。 SELECT ... FOR UPDATE
锁定执行查询时读取的所有行,而不仅仅是实际选择的行。没有索引,它必须执行完整的 table 扫描,因此每一行都会被锁定。
有了索引,它只是在该索引条目中加锁,它不必读取任何其他行,因此不会锁定其他行。