首先了解事务访问数据库读取数据会出现的情况
1、脏读 Dirty reads
事务A的未提交(还依然缓存)的数据被事务B读走,此时事务A提交失败,数据回滚,会导致事务B所读取的的数据是缓存中的错误数据。
2、不可重复读 non-repeatable reads
在A事务内,多次读同一数据。A事务还没有结束时,另外一个B事务也访问该数据,并做了修改。那么,A事务两次读到的的数据可能是不一样的,造成A事务不能读取原始数据,即为不可重复读。
3、幻读 phantom reads
幻读与不可重复读相似,但处理数据是基于数据集上的。如,在A事务内,多次查询一个表,并修改所查询数据,首次查询出的数据为100条做出了修改,A事务没有结束,此时B事务对该表插入了一条数据,当A事务再次查询该表时,发现查询出来有新的数据没有被修改,造成A事务多次查询不一致,像产生幻觉一样。
不可重复读的重点是修改:
同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除:
同样的条件,第1次和第2次读出来的记录数不一样
在不同情况下,针对上述现象,Spring事务的Isolation属性提供5中事务设置
1、DEFAULT:使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别
2、Serializable:最严格的级别,事务串行执行,资源消耗最大;
3、REPEATABLE READ:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
4、READ COMMITTED:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
5、Read Uncommitted:保证了读取过程中不会读取到非法数据。隔离级别在于处理多事务的并发问题。
级别范围如下表
脏读 | 不可重复读 | 幻读 | |
---|---|---|---|
Serializable | 不会 | 不会 | 不会 |
REPEATABLE READ | 不会 | 不会 | 会 |
READ COMMITTED | 不会 | 会 | 会 |
READ UNCOMMITTED | 会 | 会 | 会 |