数据库的隔离级别
数据库隔离级别
数据库
数据库的隔离级别
数据库一共有4种隔离级别由低到高如下
- Read uncommitted 读未提交
- Read committed 读提交
- Repeatable read 重复读
- Serializable 序列化
这4种隔离级别可以分别解决脏读,不可重复读,幻读问题。表格如下
注意 √: 可能出现 ×: 不会出现
Read uncommitted | √ | √ | √ |
Read committed | × | √ | √ |
Repeatable read | × | × | √ |
Serializable | × | × | × |
四种隔离级别的含义
-
Read uncommitted 读未提交
一个事务修改了数据但是没有提交,此时另一个事务的select会读到这个为提交的数据。eg:领导给singo的账号上打了5000但是事务没有提交,此时singo查看到自己有5000块钱。但是领导随即发现,发给singo工资的金额不对是250元,于是事务回滚了,重新提交事务。最后singo只有250块钱。于是singo就白开心了
-
Read committed 读提交
本事务读取到的是最新的数据(其他事务提交后的),问题是在同一个事务里前后两次相同的select 会读到不同的结果(不能重复读)eg:singo拿着工资卡去消费,系统读取到卡里确实有2000元,而此时她的老婆也正好在网上转账,把singo工资卡的2000元转到另 一账户,并在singo之前提交了事务,当singo扣款时,系统检查到singo的工资卡已经没有钱,扣款失败,singo十分纳闷,明明卡里有钱,为 何......
-
Repeatable read 重复读
在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的。
(当一个事务开始的时候,另一个事务不能对它进行更改)但是,会有幻读现象(稍后解释)。eg:singo的老婆工作在银行部门,她时常通过银行内部系统查看singo的信用卡消费记录。有一天,她正在查询到singo当月信用卡的 总消费金额(select sum(amount) from transaction where month = 本月)为80元,而singo此时正好在外面胡吃海塞后在收银台买单,消费1000元,即新增了一条1000元的消费记录(insert transaction ... ),并提交了事务,随后singo的老婆将singo当月信用卡消费的明细打印到A4纸上,却发现消费总额为1080元,singo的老婆很诧异,以为出 现了幻觉,幻读就这样产生了。
-
Serializable 序列化读操作会隐式获取共享锁,可以保证不同事务间的互斥。是最高的事务隔离级别,同时代价也花费最高,性能很低,一般很少使用,在该级别下,事务顺序执行,不仅可以避免脏读、不可重复读,还避免了幻像读。
注意:
1. 不可重复读的重点是修改
同样的条件,你读取过的数据,再次读取出来发现值不一样了
2. 幻读的重点在于新增或者删除
同样的条件,第 1 次和第 2 次读出来的记录数不一样
再从解决的问题的角度举几个例子
- 脏读。假如,中午去食堂打饭吃,看到一个座位被同学小Q占上了,就认为这个座位被占去了,就转身去找其他的座位。不料,这个同学小Q起身走了。事实:该同学小Q只是临时坐了一小下,并未“提交”。
- 不重复读。假如,中午去食堂打饭吃,看到一个座位是空的,便屁颠屁颠的去打饭,回来后却发现这个座位却被同学小Q占去了。
- 幻读。假如,中午去食堂打饭吃,看到一个座位是空的,便屁颠屁颠的去打饭,回来后,发现这些座位都还是空的(重复读),窃喜。走到跟前刚准备坐下时,却惊现一个恐龙妹,严重影响食欲。仿佛之前看到的空座位是“幻影”一样。
上一篇: spring boot,JPA和Atomikos实现分布式事务
下一篇: 事务的隔离级别和传播行为