四大特性ACID
原子性(Atomicity)
一致性(Consistency)
隔离性(Isolation)
持久性(Durability)
概念
脏读
读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。
可重复读
在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。通常针对数据更新(UPDATE)操作。
不可重复读
在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新(UPDATE)操作。
幻读
针对数据插入(INSERT)操作来说的
假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用
事务隔离级别(4种)
SQL 标准,MySQL 全都支持。
- 读未提交(READ UNCOMMITTED)
- 读提交 (READ COMMITTED),Oracle默认
- 可重复读 (REPEATABLE READ),MySQL默认
- 串行化 (SERIALIZABLE)
从上往下,隔离强度逐渐增强,性能逐渐变差。采用哪种隔离级别要根据系统需求权衡决定,其中,可重复读是 MySQL 的默认级别。
出现背景:解决以上脏读、不可重复读、幻读问题
只有串行化解决了全部问题(3种)
实现原理
MySQL 事务隔离其实是依靠锁来实现的,加锁自然会带来性能的损失。
读未提交:不加锁的,所以它的性能是最好的
任何事务对数据的修改都会第一时间暴露给其他事务,即使事务还没有提交
——可以读到其他事务未提交的数据,但该数据可能回滚(脏数据)——脏读
读提交:一个事务只能读到其他事务已经提交过的数据,也就是其他事务调用 commit 命令之后的数据。
——在同一事务中(本例中的事务B),事务的不同时刻同样的查询条件,查询出来的记录内容是不一样的,事务A的提交影响了事务B的查询结果,这就是不可重复读(重复读不一致问题)
可重复读:事务不会读到其他事务对已有数据的修改,及时其他事务已提交————即在整个事务(开始到提交)中读数据保持一致。但会读到其他事务新插入的数据——幻读
???
MySQL 采用了 MVVC (多版本并发控制) 的方式
串行化:
读的时候加共享锁,也就是其他事务可以并发读,但是不能写。
写的时候加排它锁,其他事务不能并发写也不能并发读。
将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束——隔离效果最好的,效果最差
使用
查询
SELECT @@tx_isolation
show variables like ‘tx_isolation’
修改隔离级别的语句是:set [作用域] transaction isolation level [事务隔离级别],
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}。
其中作用于可以是 SESSION 或者 GLOBAL,GLOBAL 是全局的,而 SESSION 只针对当前回话窗口。隔离级别是 {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} 这四种,不区分大小写。