MySQL 行级锁

标签 mysql database transactions innodb locks

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

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

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

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

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

但是当我输入时:

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

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

最佳答案

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

有了索引,它只是在该索引条目中加锁,它不必读取任何其他行,因此不会锁定其他行。

关于MySQL 行级锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39665093/

相关文章:

python - 我无法安装 mysqlclient

sql - 在 SQL 中生成递增日期的结果集

mysql - 从 Hive Shell 访问 Hive Metastore 服务器信息

mysql - 等效选项,如 MySQL 中 SQL 服务器的 openquery

database - Apache Zeppelin 如何可视化 Hbase 中的数据?

database - SQLDeveloper复制数据库

java - 实体管理器隐式事务提交

MySql:事务不检测死锁?

java - JPA和Hibernate是否在没有事务开始和提交的情况下自动更新数据库

php - 检查mysql中是否存在表