Spring事务

一、对数据操作时可能会出现的问题

1. 脏读

一个事务读到了另一个事务未提交的更新数据。未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中。即读到了最终不一定存在的数据就是脏读。

2. 不可重复度

指的是在一个事务内,两个相同的查询却返回了不同的数据。

3. 幻读

指的是当前事务不是独立执行时发生的一种现象。幻读侧重的方面是某一次的查询操作得到的结果所保证的数据状态无法支撑后续的业务操作。例如,查询某条记录是否存在,当不存在时,准备插入此记录;但是执行插入操作时,发现此记录已经存在,无法插入,此时就发生了冲突。

二、Spring事务的隔离级别

事务:是不可分割的原子操作。即一系列的操作要么同时成功,要么同时失败。

1. DEFAULT(默认隔离级别)

使用数据库本身使用的隔离级别;ORACLE(读已提交),MySQL(可重复读)。

2. READ_UNCOMMITTED(读未提交)

最低的隔离级别,有脏读、幻读、不可重复读风险。

3. READ_COMMITED(读已提交)

ORACLE的默认隔离级别,有幻读和不可重复读风险。即解决脏读。

4. REPEATABLE_READ(可重复读)

MySQL的默认隔离级别,有幻读的风险。即解决了脏读和不可重复读。

5. SERIALIZABLE(可串行化)

最高的事务隔离级别,不管有多少事务,挨个执行完一个事务的所有子事务之后,才可以执行另外一个事务里面的所有子事务,这样就解决了脏读、幻读、不可重复读的问题。

三、Spring事务传播机制

多个事务方法相互调用时,事务如何在这些方法间传播,方法A是一个事务方法,在执行过程中调用了方法B,方法B有无事务以及方法B对事务的要求不同都会使方法A事务具体执行造成影响。同时方法A的事务对方法B的事务具体执行也有影响,这种影响具体由这两个方法事务传播的具体类型所决定。

1. REQUIRED(必须,Spring默认的事务传播类型),如果当前没有事务,则创建一个事务,如果当前存在事务,则加入这个事务。

2. SUPPORTS(支持),如果当前存在事务,则加入事务,如果当前没有事务,则以非事务方法执行。

3. MANDATORY(强制),如果当前存在事务,则加入事务,如果当前没有事务,则抛出异常。

4. REQUIRES_NEW(必须新建),创建一个新事物,如果当前存在事务,则挂起该事务。

5. NOT_SUPPORTED(不支持),以非事务方法执行,如果当前存在事务,则挂起该事务。

6. NEVER(从不),不使用事务,如果当前存在事务,则抛出异常。

7. NESTED(嵌套),如果当前事务存在,则嵌套在事务中执行,否则与REQUIRED事务的操作一样(开启一个事务)。

四、Spring事务什么时候失效

Spring事务的原理是AOP,进行了切面增强,那么失效的根本原因是这个AOP不起作用了。

  1. 发生自调用,类里面使用this调用本类的方法,此时这个this不是代理类,而是UserService本身,将this改成UserService代理类即可。
  2. 方法不是public,@Transactional注解只能用于public方法上,否则事务会失效,如果非要用在非public方法上,可以开启AspectJ代理模式。
  3. 数据库不支持事务
  4. 没有被Spring管理
  5. 异常被吃掉,事务不会回滚(或者抛出的异常没有被定义,默认为RuntimeException)。

总结

事务的隔离级别越高,安全性越高,但是效率越低。

你可能感兴趣的:(spring,java,后端)