<>一、声明式事务:
/** * 声明式事务: * * 环境搭建: * 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 异常类及其子类。