Spring:事务、ACID、脏读、不可重复度、幻读

2018/09/07

事务、ACID、脏读、不可重复度、幻读

事务的特性ACID

Atomicity原子性

事务务不能做一半就不做了,要么做完,要么就不做。也就是说,事务必须是一个不可分割的整体

Consistency一致性

完成数据操作后,数据不会被迫害卷,比如A转钱给B。A扣钱,B不能没有加钱

Isolation隔离性

数据操作之间隔离例如我们update别人delete

Durability持久性

数据永久存放在磁盘

数据读问题

1.脏读

事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作。

就是读了垃圾,所以叫脏读

例子

事务A 事务B
开始事务 .
. 开始事务
查余额100元 .
取10元,余额变为90 .
. 查余额90元(脏读)
撤销事务,余额变为100元 .
. 存10元,余额变为100元
. 提交事务

结果少了10元

2.不可重复读

事务 A 读取了事务 B 已提交的更改数据。

例子

事务A 事务B
开始事务 .
. 开始事务
. 查余额100元
查余额100元 .
. 取100元,余额为0
. 提交事务
查余额0元 .

两次读的钱不一样了

3.幻读

事务 A 读取了事务 B 已提交的新增数据。

例子

事务A 事务B
开始事务 .
. 开始事务
查询今天要上的课总数为2节课 .
. 课程系统添加多了一节高数课
. 提交事务
查询今天要上的课总数为3节课 .

突然多了一节课,可恶

是的,我也觉得和不可重复读貌似没什么区别,我已经用了较为容易区别的方式描述了,幻读着重于insert,不可重复读着重于update

4.第一类丢失更新

A事务撤销覆盖了B事务提交的数据

5.第二类丢失更新

B事务覆盖了A事务提交的数据

事务隔离间级别

事务隔离级别 脏读 不可重复度 幻读 第一类丢失更新 第二类丢失更新
READ_UNCOMMITTED ×
READ_COMMITTED × ×
REPEATEDABLE_READ × × × ×
SERIALIZABLE × × × × ×

Spring的事务传播行为

之前学习一直没搞懂这些传播行为在说啥。这次写好点,让自己看明白。

传播?什么东西传播

传播行为是指当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。

例如 事务方法A 调用 事务方法B, B再A中如何运行,由B事务传播行为决定

看代码:

    @Transactional  
    void B(){  
    }
    
    @Transactional  
    void A(){  
       B();  
    }  

这就出现了事务B传播给事务A

那么对于方法A在有没有事务的情况下进行区分:

1.PROPAGATION_REQUIRED(Spring默认)

如果A没有事务,就开启一个事务;

如果A有事务,B事务加入到A事务

2.PROPAGATION_REQUIRES_NEW

如果A没有事务,就开启一个事务;

如果A有事务,挂起事务A,开启新事务运行B方法

3.PROPAGATION_NESTED

如果A没有事务,就开启一个事务;

如果A有事务,开启一个事务内嵌在事务A,B运行在嵌套的事务中。(即,如果外面的事务A失败,B事务要回滚,但是B事务失败,A事务不回滚)

4.PROPAGATION_SUPPORTS

如果A没有事务,B也不要事务。

如果A有事务,B就加入到A事务。也就是说单独调用B没有事务,但是在事务A调用B时,B就有了事务

代码例子


@Transactional(propagation = Propagation.REQUIRED)
public void methodA() {
 methodB();
// do something
}
 
// 事务属性为SUPPORTS
@Transactional(propagation = Propagation.SUPPORTS)
public void methodB() {
    // do something
}

5.PROPAGATION_NOT_SUPPORTS

B总是非事务执行

如果A有事务,挂起A事务,无事务执行B

6.PROPAGATION.NEVER

B不要事务

如果A有事务,那对不起,我要抛出异常

7.PROPAGATION_MANDATORY

单独调用B,抛出异常

如果A没有事务,那对不起,你没用,我要抛出异常

如果A有事务,B加入A

简单理解:B是个学渣,考试肯定不及格,需要抱大腿,如果A也是学渣当然也不行

spring提供给事务的额外功能

1.事务超时

事务时间太长,消耗太多资源,如果超时就回滚

2.只读事务

忽略不需要事务的方法,例如读数据。这样可以提高性能





github: https://github.com/Hikiy
作者:Hiki
创建日期:2018.09.07
更新日期:2018.09.07

(转载本站文章请注明作者和出处 Hiki

Post Directory