Spring事物原理完全解析
事务是什么?了解事务的原理吗?说下Spring的事务原理,能自己实现Spring事务原理吗?先自我检测下这些知识掌握了吗。那么接下来一起看下与Spring相关的事务
概念
事务具有ACID特性。
是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
Spring事务的底层依赖MySQL的事务,代码层面上利用AOP实现。MySQL的事务有隔离级别的概念,只有InnoDB有事务,并且实现方式是利用undo log和redo log。
AOP方面,有连接点,切点,增强,目标,织入。参考Spring AOP入门,Spring则是在代码层面执行事务的时候使用TransactionInceptor进行拦截,然后处理。
代码
在AopConfigUtils可以看到具体会生成什么类型的AutoProxyCreator,这几个都是beanPostProcessor,在Bean创建之后对Bean的实例进行自定义处理。如果使用了@EnableTransactionManagement,经过一些配置这次生成的是InfrastructureAdvisorAutoProxyCreator,具体如何生成这个类的点进去@EnableTransactionManagement里面即可。
EnableTransactionManagement
- @Import(TransactionManagementConfigurationSelector.class)
- return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
- AutoProxyRegistrar.registerBeanDefinitions中
- 创建InfrastructureAdvisorAutoProxyCreator
在Bean的生命周期中,Bean创建完成调用创建InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法。
另外AbstractAutowireCapableBeanFactory.initializeBean方法也值得一看
获取Bean的Advice,如果有Advice(增强的话),创建bean的动态代理。创建动态代理都是Spring AOP做的事情了,根据设置就是创建JDK动态代理和CGLib代理了,我们项目默认都是使用CGLib动态代理(proxyTargetClass=true即可),只说下CGlib的动态代理,主要利用了Enhancer类
这里有Enhacer用法Cglib的使用方法(1)–Enhancer
拦截接口intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)有我们根据条件进行是否要拦截的数据,根据参数就可以判断。
可以跟进去DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice方法中看
PointcutAdvisor为BeanFactoryTransactionAttributeSourceAdvisor
MethodMatcher为TransactionAttributeSourcePointcut
得到的拦截器为事务拦截器,既然是事务拦截器,那么可以跟上之前的分析了。
Spring事务原理分析
我们接着看为什么获取的拦截器是MethodInterceptor。在MethodMatcher.match中有AdvisorAdapter
而Advice是advisor中的,advisor是BeanFactoryTransactionAttributeSourceAdvisor
一种在TransactionProxyFactoryBean中默认的TransactionIntercetor
在默认的@EnableTransactionManagement注解中,将BeanFactoryTransactionAttributeSourceAdvisor的advice设置为TransactionIntercetor,这一步的注解生效,我们第一步就已经讲过了。
方法是如何匹配的,TransactionAttributeSourcePointcut中matches方法,调用TransactionAttributeSource属性判断是否有method的属性
然后调用computeTransactionAttribute(method, targetClass),判断是否有事务属性
AbstractFallbackTransactionAttributeSource.computeTransactionAttribute
-- AnnotationTransactionAttributeSource.determineTransactionAttribute 获取方法属性
-- 获取到TransactionAttribute,然后返回
到现在我们基本上解释了,Spring的事务拦截器是如何生效的,拦截器什么时候设置的,事务方法是如何匹配的。
事务不生效
private方法不会生效,JDK中必须是接口,接口中不可能有private方法,而私有方法子类无法方法,也不会生效
CGLib代理的时候,final方法不会生效,抛NullPointException
protect方法的话,默认是只允许public方法。
最后一个就是在当前的bean中非事务方法调用事务方法为什么不生效?
public int save(String name, int age) throws Exception {
insert(name, age);
return 1;
}
@Transactional
public void insert(String name, int age){
jdbcTemplate.update(insert into user(id,name,age)values(1,'+name+',+age+));
jdbcTemplate.update(insert into user(id,name,age)values(2,'+name+',+age+));
jdbcTemplate.update(insert into user(id,name,age)values(1,'+name+',+age+));
}
答:
经过最终验证,得出如下结论:
如果先调用的save方法,在进行方法拦截的时候,方法拦截器首先获取当前动态代理的对象所代理的原始对象。
比如FirstApp生成的动态代理名称为FirstApp$CGlibxxx,这个时候通过getTarget获取的对象即为FirstApp的实例。
接下来如果判断当前的方法比如save方法没有Advice(增强),则直接调用原对象的方法,即这个时候调用的是FirstApp.save方法。而不是FirstApp$CGLibxxx的save方法。可以跟代码。
最后
Spring事务这块,如果认真看我写的文章,相信你会收获不少
Spring事物原理完全解析的更多相关文章
- Spring IOC 原理深层解析
1 Spring IOC概念认识 1.1 区别IOC与DI 首先我们要知道IOC(Inverse of Control:控制反转)是一种设计思想,就是 将原本在程序中手动创建对象的控制权,交由Spri ...
- Spring声明式事物原理分析
基础准备 pom <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www. ...
- 【Spring】Spring IOC原理及源码解析之scope=request、session
一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...
- spring 事物的一些理解
推荐一个我认为Spring事物写得很好的文章. 文章链接:http://www.codeceo.com/article/spring-transactions.html 文章作者:码农网 – 吴极心 ...
- 这一次搞懂Spring事务注解的解析
前言 事务我们都知道是什么,而Spring事务就是在数据库之上利用AOP提供声明式事务和编程式事务帮助我们简化开发,解耦业务逻辑和系统逻辑.但是Spring事务原理是怎样?事务在方法间是如何传播的?为 ...
- Spring:源码解读Spring IOC原理
Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...
- spring MVC原理
spring MVC原理 Spring MVC工作流程图 图一 图二 Spring工作流程描述 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt D ...
- spring原理案例-基本项目搭建 03 创建工程运行测试 spring ioc原理实例示例
下面开始项目的搭建 使用 Java EE - Eclipse 新建一 Dynamic Web Project Target Runtime 选 Apache Tomcat 7.0(不要选 Apache ...
- Spring IOC原理解读 面试必读
Spring源码解析:Bean实例的创建与初始化 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. IoC容器 ...
随机推荐
- SSO详解(转)
转自:http://www.cnblogs.com/EzrealLiu/p/5559255.html 1. 摘要 SSO这一概念由来已久,网络上对应不同场景的成熟SSO解决方案比比皆是,从简单到复杂, ...
- 浅析Android View(二)
深入理解Android View(一) View的位置參数信息 二.View的绘制过程 View的绘制过程一共分为三个部分: - measure(測量View的大小) - layout(确定View的 ...
- jquery Chosen使用
1,首先去http://harvesthq.github.io/chosen/下载插件. 2,在网页中加入下面的文件. <link rel="stylesheet" href ...
- .net操作xml文件(新增.修改,删除,读取) 转
今天有个需求需要操作xml节点.突然见遗忘了许多.上网看了些资料.才整出来.脑袋真不够用.在这里把我找到的资料共享一下.方便以后使用.本文属于网摘/ 1 一.简单介绍2 using System.Xm ...
- Mysql 5.7 主从复制
配置思路1. 修改master和slave的配置文件,使用二进制日志,指定serverid目的是让各自都有了自己的唯一标示,并以二进制文件格式进行交流2. master中创建授权用户,查看二进制日志文 ...
- JMeter5.0 边界提取器使用
需求: 需要提取下图中requestNo的值,使用JMeter3.1和4.0版本,使用正则表达式提取器始终无法获取 而后使用JMeter5.0的边界提取器,不需要写复杂的正则表达式,只要填写左右边界即 ...
- python3_UUID模块详解
1.知识背景 UUID是128位的全局唯一标识符,通常有32字节的字母表示.它可以保证时间和空间的唯一性. UUID——Universally unique identifier 在python中叫U ...
- Python --之练习题
一,两个小组对战,对战规则如下:team1 = ['a','b','c']team2 = ['x','y','z'] #a 不和x对战,b 不和y,z 对战# for i in team1: #法一# ...
- ISO8583
最开始时,金融系统只有IBM这些大的公司来提供设备,象各种主机与终端等.在各个计算机设备之间,需要交换数据.我们知道数据是通过网络来传送的,而在网络上传送的数据都是基于0或1这样的二进制数据,如果没有 ...
- 20145216史婧瑶《Java程序设计》第一次实验报告
实验一 Java开发环境的熟悉(Linux + Eclipse) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 1.没 ...