事务隔离级别深入理解
- Mysql事务级ACID特性详解
- Mysql事务隔离级别详解
- Mysql锁机制详解
- Mysql锁优化建议
事务隔离级别ACID
事务及其ACID属性。
事务的特性 ACID:
ACID是原子性,一致性,持久性,独立性的缩写。
原子性:一个操作不是成功就是失败,要么执行成功,要么执行失败。
一致性:事务的索引规则,约束等不受破坏。事务开始中,所有相关的数据结果都必须保持状态一致,比如一个事务对三个数据进行修改,事务结束后三个状态必须都是被修改过的,保持一致。
隔离性: 每个事务之间不要相互影响。A事务查的结果不要被别的影响。就是说A事务执行过程中,结果集不能变。
持久性:事务完成后的对结果产生影响要持久。不能一会儿变来变去。
并发事务带来的问题
- 更新丢失(脏写)
事务A对数据进行+1,事务B对数据进行-1。B的更新操作把A覆盖掉了。
- 脏读
事务A读取了事务B还未提交的数据,但是事务B进行了回滚。事务A读到了脏数据。
- 不可重复读
事务A读取了数据1,但是被B修改成了2,事务A再读变成了2。与之前的不同。
- 幻影读
事务A,count了一个数据块,事务B插入了一条数据,事务A再进行count的 时候数据变了。
以上问题都是事务隔离性问题。所以要引入事务隔离级别来解决这些问题。
事务隔离级别
事务隔离级别是Mysql提供的预设的几种级别。
- 未提交读:事务T在读取数据的时候并未对数据进行加锁,事务T在修改数据的时候对数据增加行级共享锁,这种隔离级别没解决脏读。
- 已提交读:事务T在读取数据时增加行级共享锁,读取一旦结束,立即释放;事务T在修改数据时增加行级排它锁,直到事务结束才释放,这种隔离级别解决了脏读。
- 可重复读:事务T在数据读取时,必须增加行级共享锁,直到事务结束;事务T在修改数据过程中,必须增加行级排它锁,直到数据结束;这种隔离级别没解决幻读。
- 序列化:事务T在读取数据时,必须先增加表级共享锁,直到事务结束时才释放;事务T在修改数据时,必须先增加表级排它锁,直到事务结束才释放。
这些隔离级别采用的是
MVCC:multi version concurrency controller
锁机制详解
锁机制是事务隔离级别的实现方式
锁分类
性能上分:悲观锁,乐观锁。
数据库操作上分:读锁,写锁。
从数据库的操作力度来分:表锁,行锁。
- 表锁
开销小,加锁快。锁力度大, 一般在离线操作数据迁移的时候进行,比较少会用。 - 读锁(s)
可以进行共享读。 - 写锁(x)
不能进行写。也不能进行读。
重点
- 行锁
开销大,加锁慢。
innodb支持行锁。支持事务。 - 间隙锁
innodb采用间隙锁,在可重复读级别解决了幻读问题。 - 临键锁(next-ke)
行锁 + 间隙锁
锁优化建议
行锁分析
1 | show status like 'innodb_row_locks' |
1 | -- 查看事务 |
锁优化建议
- 尽可能让所有数据检索都通过索引来完成,避免误索引锁升级为表锁。
- 合理设计索引,尽量缩小锁的范围。
- 尽可能减少检索条件范围,避免间隙锁。
- 尽量控制事务大小,减少锁定资源和时间长度,涉及事务加锁的sql尽量放在事务后执行。
- 尽可能低级别事务隔离。