在不通过索引条件查询的时候 , InnoDB使用的是表锁!
当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论 是使用主键索引、唯一索引或普通索引,InnoDB 都会使用行锁来对数据加锁 。
即便在条件中使用了索引字段,但是否使用索引来检索数据是由 MySQL 通过判断不同 执行计划的代价来决定的,如果 MySQL 认为全表扫 效率更高,比如对一些很小的表,它 就不会使用索引,这种情况下 InnoDB 将使用表锁,而不是行锁 。因此,在分析锁冲突时, 别忘了检查 SQL 的执行计划(explain查看),以确认是否真正使用了索引 。
三、Mysql的隔离机制Read uncommitted 读未提交:READ UNCOMMITTED级别忽略其它事务放置的锁 。使用READ UNCOMMITTED级别运行的事务 , 能够读取尚未由其它事务提交的改动后的数据值 , 这些行为称为“脏”读 。我们所说的脏读 , 两个并发的事务 , 事务A可以读取到事务B未提交的数据 。假设事务A回滚 , 事务B就读取了一行没有提交的数据 。这种数据我们觉得是不存在的 。
Read committed 读提交:一个事务只能读取另一个事务已经提交的修改 。其避免了脏读 , 但仍然存在不可重复读和幻读问题 。大多数数据库的默认级别就是Read committed 。比方Sql Server , Oracle 。
Repeatable read 反复读:该级别指定了在当前事务提交之前 , 其它不论什么事务均不能够改动或删除当前事务已读取的数据 。并发性低于 READ COMMITTED 。由于已读数据的共享锁在整个事务期间持有 , 而不是在每一个语句结束时释放 。这个隔离级别仅仅是说 , 不可以改动和删除 , 可是并没有强制不能插入新的满足条件查询的数据行 。所以会产生“幻读”;Mysql的默认隔离级别就是Repeatable read
Serializable 串行读:完全串行化的读 , 每次读都需要获得表级共享锁 , 读写相互都会阻塞
| 隔离级别 | 读数据一致性 | 脏读 | 不可重复读 | 幻读 |
| 未提交读(Read uncommitted) | 最低级别隔离 , 只能保证不读取物理上损坏的数据 | 是 | 是 | 是 |
| 已提交读(Read committed) | 语句级别 | 否 | 是 | 是 |
| 可重复读(Repeatable read) | 事务级别 | 否 | 否 | 是 |
| 可序列化(Serializable) | 最高级别 , 事务级 | 否 | 否 | 否 |
- 脏读(Drity Read):某个事务已更新一份数据 , 另一个事务在此时读取了同一份数据 , 由于某些原因 , 前一个RollBack了操作 , 则后一个事务所读取的数据就会是不正确的 。
- 不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致 , 这可能是两次查询过程中间插入了一个事务更新了原有的数据 。不可重复读主要针对的是update与delete
- 幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致 , 例如有一个事务查询了几列(Row)数据 , 而另一个事务却在此时插入了新的几列数据 , 先前的事务在接下来的查询中 , 就会发现有几列数据是它先前所没有的 。幻读主要是针对insert;
在InnoDB中 , 会在每行数据后添加两个额外的隐藏的值来实现MVCC , 这两个值一个记录这行数据何时被创建 , 另外一个记录这行数据何时过期(或者被删除) 。在实际操作中 , 存储的并不是时间 , 而是事务的版本号 , 每开启一个新事务 , 事务的版本号就会递增 。在可重读Repeatable reads事务隔离级别下:
- SELECT时 , 读取创建版本号<=当前事务版本号 , 并且会移除版本号为空或>当前事务版本号的数据行 。
- INSERT时 , 保存当前事务版本号为行的创建版本号
- DELETE时 , 保存当前事务版本号为行的删除版本号
- UPDATE时 , 插入一条新纪录 , 保存当前事务版本号为行创建版本号 , 同时保存当前事务版本号到原来删除的行
推荐阅读
- Wps中如何快速突显重复值?
- 如何成为一名后端开发工程师
- 螃蟹怎样挑选肥的 如何挑选螃蟹肥瘦
- 衣服染色用84怎么洗掉 84染色的衣服怎么洗掉如何用墨水上色
- 薄荷饮品的制作,如何制作薄荷红茶
- 如何成功转行AI算法工程师
- 浅表性胃炎如何根治,慢性浅表性胃炎六如何根治
- 如何用python实现自动化办公
- 如何把青香蕉变成黄香蕉 香蕉发青怎么变黄
- 如何用三明治机煎蛋 三明治机怎么煎鸡蛋吗
