目录

  • 1 spring事务概念
  • 2 事务有四个特性:ACID
  • 3 声明式事务,xml配置类的形式
  • 4 声明式事务,注解的形式
  • 5 @Transactional()
  • 6 为什么要有不同的事务传播特性
  • 7 有7个传播特性
  • 7.1propagation_never
  • 7.2 propagation_not_supported:
  • 7.3 propagation_supported
  • 7.4 propagation_requires_new
  • 7.5 propagation_nested
  • 7.6 propagation_require
  • 7.7 propagation_mandatory
  • 8 底层原理


1 spring事务概念

事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。

2 事务有四个特性:ACID

原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

3 声明式事务,xml配置类的形式

项目中,一个方法里面有多个操作数据库的语句,比如转账,一个人减少钱,一个人增加钱,这个方法就需要放到事务里面;

事务就是同一个数据库连接对象进行操作数据库,而且需要事务管理器,我们的spring项目中,在xml里面进行配置就可以,一次配置,以后就不需要改了,以后每一个service方法,都被事务控制,那么如何在xml里面进行配置

spring实现事务原理 spring事务的原理是什么_spring实现事务原理


使用AOP的形式,将service层 的方法,都放到了事务里面

4 声明式事务,注解的形式

我们写一个配置类,里面就是数据源的那些配置,在类上面,写一个注解,开启使用注解的形式进行配置

Spring提供了一个@EnableTransactionManagement注解在配置类上开启声明式的支持。使用了@EnableTransactionManagement后,Spring容器会自动扫描@Transactional的方法和类。
之后在对应的类上面,或者方法上面写一个注解
@Transactional,对应的方法就进入了事务里面了;

5 @Transactional()

这个注解里面可以配置什么,我们看源码

源码

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    @AliasFor("transactionManager")
    String value() default "";   这个代表使用哪个事务管理器

    @AliasFor("value")
    String transactionManager() default "";

事务的传播特性
    Propagation propagation() default Propagation.REQUIRED;


隔离级别
    Isolation isolation() default Isolation.DEFAULT;

    int timeout() default -1;

    boolean readOnly() default false;

    Class<? extends Throwable>[] rollbackFor() default {};

    String[] rollbackForClassName() default {};

    Class<? extends Throwable>[] noRollbackFor() default {};

    String[] noRollbackForClassName() default {};
}

6 为什么要有不同的事务传播特性

事务传播特性是什么?

就是有两个方法A和B方法,两个方法都有事务,A方法如果调用B方法,A方法出错了,A方法的事务回滚了,那么B方法的需要回滚嘛?反之,B方法出错了,他进行了回滚,A方法需要回滚嘛?

所以就有了不同的传播特性,有的业务里面,都需要回滚,有的就不需要,看业务进行设置

7 有7个传播特性

分为两大类

spring实现事务原理 spring事务的原理是什么_回滚_02


propagation_never :

就是A方法调用B方法 的时候,两个都没有事务,如果A方法有事务,那么就抛出异常;

这个事务传播特性是在B方法上面进行配置的

propagation_not_supported:
就是A 方法有事务,事务的类型是什么,那么当里面调用其他B方法的时候,先执行B方法,B方法不归当前A里面的事务管,当B方法执行完成之后,如果出错也不回滚,A里面的东西继续执行,如果出错就回滚;

propagation_supported:
可有可无,有就用,没有就不用

propagation_requires_new:
必须有一个事务,就是A方法调用B方法,B方法必须有事务,如果A方法没有事务,那么就好,如果A方法也有事务,那么就把A方法挂起,当B里面执行完成之后,A方法再执行

7.1propagation_never

A方法调用B方法,B方法上面写了这个注解,并且配置了事务的传播特性是propagation_never,那么A方法上面不能有事务注解,不然会报错,

7.2 propagation_not_supported:

A调用B,两个都有事务,B事务的传播特性是propagation_not_supported:,意思是B方法没有事务,而且这个方法不归其他事务管,就是告诉其他事务,我不归你管,我出错了,也不会回滚

7.3 propagation_supported

A调用B,B上面写这个传播特性,那么这个时候,如果A有事务,B就加进去,如果A没有事务,那么B也没有

7.4 propagation_requires_new

不管你有没有,我都会新建一个;
如果A调用B,A没有事务,B有事务,事务的传播是propagation_requires_new
那么B一定会自己新创建一个事务;

A有事务,B有事务,事务的传播是propagation_requires_new
会将A 挂起;
相当于两个事务互不影响

7.5 propagation_nested

嵌套事务

A方法调用B,b的传播特性是propagation_nested
A和B都有事务,当B 出错,A没有,那么A不会回滚,B会回滚
当A出错,B没有出错,A和B都会回滚

就是外面的大环境出错,会影响里面的多有,里面的某一个出错,不会影响外面的

7.6 propagation_require

A没有就新建,A有就用A 的事务

7.7 propagation_mandatory

A必须有事务,如果A没有,就报错

8 底层原理

首先我们要知道,spring对事务的处理,就是使用aop,就是一个功能的扩展,之前我们已经知道,spring的aop是有前置通知,后置通知之类的东西,意思就是在我们原来的方法上面,进行扩展功能,可以在原来方法 的前面执行一些语句,之后执行一些语句,最后变成一个代理类,我们的这个代理类,就是功能扩展之后的类,以后直接使用这个代理类,就可以了,里面就是有很多的功能了