Mysql的行锁,改一行锁一行

前言

在 MySQL 数据库中,提供锁机制这个功能的是存储引擎,如果需要使用行锁就必须使用支持行锁的存储引擎。在 MySQL 数据库中,MyISAM 存储引擎是不支持行级锁的,支持行锁的是 InnoDB 存储引擎,这也是 MySQL 数据库后来选择 InnoDB 存储引擎为默认存储引擎的原因之一。

行级锁的功能是跟表级锁类似,都是用来锁定数据的,用来防止并发导致数据修改失败这种情况的出现。所不同的是表锁是锁定整个表的数据,而行级锁是操作一行、锁定一行,并且行级锁也是 MySQL 中粒度最小的锁

当操作某个数据表中的数据使用表级锁时,整个数据表中所有的数据都会被锁定而无法操作,也就是同一时间只能有一个修改操作,这是非常影响数据库并发的,不适合访问量大的场景。而行级锁是操作一行、锁定一行,所以在最大程度上减少了数据表中多个操作之间的冲突,进而提升了数据库数据更新的并发。

行级锁

行级锁就是将修改一行、锁住一行。但这里有一点我们需要注意:行级锁是产生于一个事务之中的,当事务提交或者回滚之后,行级锁立即自动释放。

在 MySQL 数据库中行级锁主要有两种,分别是:共享锁与排他锁。

1. 共享锁(Shared Lock)

共享锁又称为读锁,也可以简称为:S 锁。添加共享锁的语句为:lock in share mode。当多个事务同一时间修改同一条数据时,共享锁只允许其中的一个事务修改数据,读数据则不限制。

通常情况下,共享锁的使用场景是保证数据库中数据与数据之间的关系。举个例子:我们在购物时,总是会让我们添加地址;在填写地址之时,首先会让我们选择省份,其次是市,最后是详细的地址。在这个场景中,如果我们需要添加浦东新区的话,就意味着上海市这个上级选项必须存在。假设,我们添加浦东新区时,恰好其他人把上海市删除;那此时,我们添加的浦东新区就失去了它的意义。

为了防止这个情况的发生,我们最好添加一个锁机制,这个锁机制既不影响数据库的正常读,又能保证数据关系一致。在这种场景下,我们正好用到共享锁。

下面我们利用上面填写地址的例子,来描述一下共享锁的使用场景。

步骤 1,在事务一中开启一个共享锁,在事务二中测试共享锁是否影响查询:

-- 在事务二中查询该条数据,发现添加了共享锁的数据仍然可以正常查询。
mysql> select * from province where id = 1;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | 上海市     |
+----+-----------+
1 row in set (0.08 sec)

在这里插入图片描述
可以看出,增加了共享锁之后,其他事务中该条数据是可以正常查询的。

步骤 2,当加上共享锁之后,添加浦东新区,同时删除上海市:

在事务1中增加共享锁,同时增加一条数据

<
<think>好的,我现在需要回答用户关于MySQL作用对象的问题。根据用户提供的参考资料,我需要仔细梳理这些信息,确保回答准确。 首先,用户引用了四篇资料,其中引用[1]提到定的是具体的数据。引用[2]指出加对象是索引,基本单位是next-key lock,并且对于唯一索引和非唯一索引有不同的范围。引用[3]和[4]提供了具体的加方式和类型,比如共享锁排他,以及如何查看的信息。 接下来,我需要整理这些信息。的作用对象确实是索引,而不是物理上的数据。这是因为InnoDB使用索引来实现。如果没有索引,会退化为表,这会影响并发性能。例如,当使用主键索引(唯一索引)时,定的范围更精确,可能只是记录,而非唯一索引可能需要间隙或next-key lock来避免幻读。 另外,需要注意的类型和模式,比如记录、间隙、next-key lock的区别,以及意向的作用。引用[4]中的ENGINE_TRANSACTION_ID和LOCK_DATA等字段可以帮助理解的具体信息,比如定的主键值。 可能用户还会混淆和表的区别,需要明确说明的粒度更细,只有在有合适索引的情况下才能生效。此外,不同事务隔离级别对的影响,比如可重复读(RR)和读已提交(RC)下为不同,但用户的问题主要聚焦在定对象,所以这部分可能不需要深入展开。 最后,确保回答结构清晰,分点说明,并引用相关文献支持每个观点。同时,生成的相关问题要围绕的机制、不同索引的影响以及优化等方面,帮助用户进一步了解。</think>### MySQL的作用对象解析 MySQL(Row-level Lock)的定对象是**索引项**,而非物理数据。这一机制与存储引擎的实现密切相关,尤其是InnoDB引擎通过索引实现。以下是具体分析: --- #### 1. **基于索引** - **核心机制**:InnoDB的通过索引实现。如果查询条件未使用索引,会退化为**表级**,导致并发性能下降[^2][^4]。 - **示例**: - 对主键(唯一索引)的条件查询(如`WHERE id=1`),会直接在索引项上加。 - 非唯一索引的查询可能需要加**间隙**(Gap Lock)或**next-key lock**,以防止其他事务插入导致幻读。 --- #### 2. **的粒度与索引类型** - **唯一索引**:定**具体索引项**或**记录**(Record Lock),范围更精确。例如: ```sql SELECT * FROM user WHERE uid=1 FOR UPDATE; -- 对uid=1的主键索引加排他 ``` - **非唯一索引**:可能扩展为**间隙**或**next-key lock**,定一个索引范围。例如: ```sql -- 假设age是非唯一索引,且存在age=20的记录 SELECT * FROM user WHERE age=20 FOR UPDATE; -- 可能定age=20的索引项及相邻间隙,阻止其他事务插入age=20的数据 ``` --- #### 3. **的查看与验证** 通过`INNODB_LOCKS`或`performance_schema.data_locks`表可查看的详细信息[^4]: - `LOCK_TYPE`:`RECORD`表示。 - `INDEX_NAME`:显示定的索引名称(如`PRIMARY`)。 - `LOCK_DATA`:记录定的具体索引值(如主键值`7742`)。 --- #### 4. **特殊场景与注意事项** - **无索引查询**:若条件字段无索引,退化为**表级**,此时并发写操作会被阻塞[^1]。 - **意向(Intention Locks)**:表级,用于快速判断表中是否存在(如`IX`意向排他)[^3]。 --- ### 总结 MySQL定对象是**索引项**,其具体为取决于索引类型(唯一/非唯一)和查询条件。合理设计索引是优化并发性能的关键[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休居士

感谢您的支持,我会继续努!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值