Spring声明式事物原理分析
基础准备 pom
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springannotation.test</groupId>
<artifactId>NddSpring</artifactId>
<version>1</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.12.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.12.RELEASE</version>
</dependency> <dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
</dependencies> </project>
基础准备 配置
package com.lkd.config; import javax.sql.DataSource; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement; import com.lkd.aop.LogAspects;
import com.lkd.aop.MathCalculator;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; @Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.lkd")
@EnableTransactionManagement
public class AopConfig { @Bean
public MathCalculator calu() {
return new MathCalculator();
} @Bean
public LogAspects aspects() {
return new LogAspects();
}
@Bean
public Object obj() {
return new Object();
} @Bean
public DataSource student() throws Exception {
ComboPooledDataSource student =new ComboPooledDataSource();
student.setUser("root");
student.setPassword("123456");
//student.setDriverClass("com.mysql.jdbc.driver");
student.setDriverClass("com.mysql.jdbc.Driver");
student.setJdbcUrl("jdbc:mysql://localhost:3306/mytransction");
return student;
}
@Bean
public DataSource student2() throws Exception {
ComboPooledDataSource student =new ComboPooledDataSource();
student.setUser("root");
student.setPassword("123456");
//student.setDriverClass("com.mysql.jdbc.driver");
student.setDriverClass("com.mysql.jdbc.Driver");
student.setJdbcUrl("jdbc:mysql://localhost:3306/myt2");
return student;
} @Bean
public JdbcTemplate jdbcTemplate1(DataSource student) {
return new JdbcTemplate(student);
}
@Bean
public JdbcTemplate jdbcTemplate2(DataSource student2) {
return new JdbcTemplate(student2);
} @Bean
public MysqlDataSource student3() {
MysqlDataSource student = new MysqlDataSource();
student.setUser("root");
student.setPassword("123456");
//student.setDriverClass("com.mysql.jdbc.driver");
student.setURL("jdbc:mysql://localhost:3306/myt2");
return student; }
@Bean
public JdbcTemplate jdbcTemplate3(DataSource student3) {
return new JdbcTemplate(student3);
} @Bean
public PlatformTransactionManager txmanager() throws Exception {
return new DataSourceTransactionManager(student());
}
}
开始分析
@EnableTransactionManagement 开启声明式事务功能
为容器中导入TransactionManagementConfigurationSelector,它又会容器中导入 AutoProxyRegistrar(imp BeanDefinitionRegister)其作用为容器注入 InfrastructureAdvisorAutoProxyCreator 自动代理增强组件;利用后置处理器机制在对象创建以后
包装对象返回一个代理对象;
ProxyTransactionManagementConfiguration 给容器注入事物增强器 (解析注解) AnnotationTransactionAttributeSource;给容器中注入事物拦截器 TransactionInterceptor ,保存了事物属性信息包括事务管理器
a: 先获取事物属性TransactionAttribute,再获取PlatformTransactionManager平台事物管理器,未在Transctional注解中指定事物,则会在ioc容器中根据PlatFormTransctionManager类型的事物管理器对象
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* {@inheritDoc}
* @return {@link ProxyTransactionManagementConfiguration} or
* {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
* {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
执行过程中出现异常
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
throws Throwable { // If the transaction attribute is null, the method is non-transactional.
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
completeTransactionAfterThrowing(txInfo, ex);//出现异常进行回滚
throw ex;
}
finally {
cleanupTransactionInfo(txInfo);
}
commitTransactionAfterReturning(txInfo);
return retVal;
}
总结 : 事物实际上在spring维度是对AOP的应用,掌握了Aop原理,事物则会理解起来贼tm容易。如果AOP不清楚的可以看我Aop解析。
https://www.cnblogs.com/leaveast/p/10829917.html
Spring声明式事物原理分析的更多相关文章
- spring 声明式事务原理解读
在Spring中,声明式事务是通过事务属性(transaction attribute)来定义的.事务属性描述了事务策略如何应用到方法上.事务属性包含5个方面: 传播行为 隔离级别 是否只 ...
- 浅谈spring 声明式事物
此处主要讲讲事物的属性. 事物属性包含了五个方面: 1.传播行为 2.隔离规则 3.回滚规则 4.事物超时 5.是否只读 一.传播行为 事务的第一个方面是传播行为(propagation behavi ...
- Spring学习之声明式事物管理
public List<Student> selectStudent() { Student s = new Student(); s.setName("zhengbin&quo ...
- SSH学习——声明式事物管理(Spring)
1.什么是事物? 事务是一组操作的执行单元,相对于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等,事务的一致性,要求,这个事务内的操作必须全部执行成功,如果在此过程种出现了差错,比 ...
- Spring声明式事务管理基于@Transactional注解
概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解. 第一种方式我已在上文为大 ...
- spring5 源码深度解析----- @Transactional注解的声明式事物介绍(100%理解事务)
面的几个章节已经分析了spring基于@AspectJ的源码,那么接下来我们分析一下Aop的另一个重要功能,事物管理. 事务的介绍 1.数据库事物特性 原子性多个数据库操作是不可分割的,只有所有的操作 ...
- spring声明式事务管理总结
事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...
- Spring声明式事务配置管理方法
环境配置 项目使用SSH架构,现在要添加Spring事务管理功能,针对当前环境,只需要添加Spring 2.0 AOP类库即可.添加方法: 点击项目右键->Build Path->Add ...
- 161117、使用spring声明式事务抛出 identifier of an instance of
今天项目组有成员使用spring声明式事务出现下面异常,这里跟大家分享学习下. 异常信息: org.springframework.orm.hibernate3.HibernateSystemExce ...
随机推荐
- 前端开发中的 MVC、MVP、MVVM 模式
MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...
- mcast_block_source函数
#include <errno.h> #include <sys/socket.h> #define SA struct sockaddr int mcast_block_so ...
- selenium 获取table数据
public class Table { /** * @param args */ public static void main(String[] args) { // TODO Auto-gene ...
- Cookie信息保存到本地(MozillaCookieJar)
from urllib import request from http.cookiejar import MozillaCookieJar cookiejar = MozillaCookieJar( ...
- PCF8591 AD/DA模块使用详解
I2C PCF8591 8位AD/DA转换 BCM2835 Library 1.PCF8591T简述 PCF8591器件图如下: PCF8591是一个8位的CMOS数据采集器件,具有4个模拟输入(其中 ...
- redhat 7.6 安装 inotify-tools 文件监控工具 搭配rsync
1.解压inotify-tools tar -zxvpf inotify-tools-3.14.tar.gz 2.cd 到解压的目录 3../configure 编译,然后失败,提示checking ...
- 通过Java创建XML(中文乱码已解决)
package com.zyb.xml; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.Ou ...
- windows下pycharm连接vagrant的python环境
- activiti 全局流程监听ActivitiEventListener,实现监听不同类型事件,不需要在acitivit中配置任务监听,非常方便
如果我们像给任务配置监听,按照常规的做法是这样的 一个个配置,比较麻烦. 现在利用ActivitiEventListener,监听全局事件,并且可以判断不同的事件类型,进而执行不同的业务逻辑. 1.定 ...
- js加密(十)csti.cn md5
1. http://www.csti.cn/index.htm 2. 登录密码加密 3. 加密js: var hexcase = 0; var b64pad = ""; var c ...