Spring 事务底层原理

一、声明式事务:

/**
* 声明式事务:
*
* 环境搭建:
* 1、导入相关依赖
*         数据源、数据库驱动、Spring-jdbc模块
* 2、配置数据源、JdbcTemplate(Spring提供的简化数据库操作的工具)操作数据
* 3、给方法上标注 @Transactional 表示当前方法是一个事务方法;
* 4、 @EnableTransactionManagement 开启基于注解的事务管理功能;
*         @EnableXXX
* 5、配置事务管理器来控制事务;
*         @Bean
*         public PlatformTransactionManager transactionManager()
*
*
* 原理:
* 1)、@EnableTransactionManagement
*             利用TransactionManagementConfigurationSelector给容器中会导入组件
*             导入两个组件
*             AutoProxyRegistrar
*             ProxyTransactionManagementConfiguration
* 2)、AutoProxyRegistrar:
*             给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件;
*             InfrastructureAdvisorAutoProxyCreator:?
*             利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;
*
* 3)、ProxyTransactionManagementConfiguration 做了什么?
*             1、给容器中注册事务增强器;
*                 1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
*                 2)、事务拦截器:
*                     TransactionInterceptor;保存了事务属性信息,事务管理器;
*                     他是一个 MethodInterceptor;
*                     在目标方法执行的时候;
*                         执行拦截器链;
*                         事务拦截器:
*                             1)、先获取事务相关的属性
*                             2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger
*                                 最终会从容器中按照类型获取一个PlatformTransactionManager;
*                             3)、执行目标方法
*                                 如果异常,获取到事务管理器,利用事务管理回滚操作;
*                                 如果正常,利用事务管理器,提交事务
*             
*/

二、Spring 事务原理

二、事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

三、spring事务失效的原因

1、数据库引擎不支持事务
2、没有被 Spring 管理
3、方法不是 public 的
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.
4、自身调用问题
发生了自身调用,就调该类自己的方法,而没有经过 Spring 的代理类,默认只有在外部调用事务才会生效
5、数据源没有配置事务管理器
6、@Transactional中的事务传递配置错误
7、异常被吃了,方法A引用支持事务的方法B,但是catch了方法B的异常,导致B事务失效
8、异常类型错误
默认回滚的是:RuntimeException,如果你想触发其他异常的回滚,需要在注解上配置一下,如:
@Transactional(rollbackFor = Exception.class)

这个配置仅限于 Throwable 异常类及其子类。

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