基础准备 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声明式事物原理分析的更多相关文章

  1. spring 声明式事务原理解读

    在Spring中,声明式事务是通过事务属性(transaction attribute)来定义的.事务属性描述了事务策略如何应用到方法上.事务属性包含5个方面:   传播行为   隔离级别   是否只 ...

  2. 浅谈spring 声明式事物

    此处主要讲讲事物的属性. 事物属性包含了五个方面: 1.传播行为 2.隔离规则 3.回滚规则 4.事物超时 5.是否只读 一.传播行为 事务的第一个方面是传播行为(propagation behavi ...

  3. Spring学习之声明式事物管理

    public List<Student> selectStudent() { Student s = new Student(); s.setName("zhengbin&quo ...

  4. SSH学习——声明式事物管理(Spring)

    1.什么是事物? 事务是一组操作的执行单元,相对于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等,事务的一致性,要求,这个事务内的操作必须全部执行成功,如果在此过程种出现了差错,比 ...

  5. Spring声明式事务管理基于@Transactional注解

    概述:我们已知道Spring声明式事务管理有两种常用的方式,一种是基于tx/aop命名空间的xml配置文件,另一种则是基于@Transactional 注解.         第一种方式我已在上文为大 ...

  6. spring5 源码深度解析----- @Transactional注解的声明式事物介绍(100%理解事务)

    面的几个章节已经分析了spring基于@AspectJ的源码,那么接下来我们分析一下Aop的另一个重要功能,事物管理. 事务的介绍 1.数据库事物特性 原子性多个数据库操作是不可分割的,只有所有的操作 ...

  7. spring声明式事务管理总结

    事务配置 首先在/WEB-INF/applicationContext.xml添加以下内容: <!-- 配置事务管理器 --> <bean id="transactionM ...

  8. Spring声明式事务配置管理方法

    环境配置 项目使用SSH架构,现在要添加Spring事务管理功能,针对当前环境,只需要添加Spring 2.0 AOP类库即可.添加方法: 点击项目右键->Build Path->Add ...

  9. 161117、使用spring声明式事务抛出 identifier of an instance of

    今天项目组有成员使用spring声明式事务出现下面异常,这里跟大家分享学习下. 异常信息: org.springframework.orm.hibernate3.HibernateSystemExce ...

随机推荐

  1. Vue项目——去哪网(首页部分)

    业务逻辑 通过gitee创立各个分支,比如swiper,header,recommende等分支,其实就是整个页面上的每个模块.模块化是公司级别项目开发的基准,每个人在各自的分支上进行代码的编写,而对 ...

  2. 修复GRUB引导故障!

    故障原因:MBR中的GRUB引导程序遭到破坏,grub.conf文件丢失,引导配置有误 故障现象:系统引导停滞,显示“grub>”提示符 解决思路:若无MBR备份,进入急救模式,重新安装grub ...

  3. Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig

    Caused by: java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig at ...

  4. ubuntu-18.04 修改用户名密码

    1. 开放root登录 设置root密码 $ sudo passwd root 切换到root 用户 $ sudo -i 修改/etc/pam.d/gdm-autologin $ vim /etc/p ...

  5. IDEA快捷键/本文仅供自己参考使用如有侵权立删

    好好来学习学习IDEA这款神器,让你的效率飞起!视频来自慕课网 本文转载 更多技巧 代码定位 跳转: 1.IDEA的左侧侧边栏有1:Project.7:Structure和2:Favorities a ...

  6. GO 回调实现

    函数作为参数传递,实现回调. package main import "fmt" // 声明一个函数类型 type cb func(int) int func main() { t ...

  7. 七 Spring的IOC的注解方式

    Spring的IOC的注解方式入门 引入注解约束,配置组件扫描 类上的注解: @Conponent  @Controller @Service @Repository 普通属性的注解   @value ...

  8. Servlet 学习(四)

    HTTP 响应的构成1.HTTP 响应行: 协议.状态.描述 HTTP 1.1 中定义的状态代码 100-199 是信息性代码,标示客户应该采取的其它动作 200-299 表示请求成功 300-399 ...

  9. Python学习第十二课——json&pickle&XML模块&OS模块

    json模块 import json dic={'name':'hanhan'} i=8 s='hello' l=[11,22] data=json.dumps(dic) #json.dumps() ...

  10. Codeforces1307C. Cow and Message

    读题,我们知道选1个.选2个的时候是没有冲突的,大于2个的时候就有限制,那么我们观察是否可以把大于2个的情况都转换一下,可以发现,如果有一个串的长度大于2,且出现的次数大于2,那么,组成这个串里必定有 ...