【Spring实战】----Spring事务管理配置解析
上篇说了aop的配置,并且说了Spring事务管理是基于aop的,那么Spring声明式事务的配置就有两种方式:XML配置及注解配置
不多说,直接看配置文件
一、配置文件
applicationContext-transaction.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "><bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean><!-- 通知 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- 传播行为 --><tx:method name="save*" propagation="REQUIRED"/><tx:method name="delete*" propagation="REQUIRED"/><tx:method name="insert*" propagation="REQUIRED"/><tx:method name="update*" propagation="REQUIRED"/><tx:method name="list*" propagation="SUPPORTS" read-only="true"/><tx:method name="get*" propagation="SUPPORTS" read-only="true"/></tx:attributes></tx:advice><!-- aop --><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* com.mango.jtt.service.*.*(..))"/></aop:config><!-- 注解管理事务 --><tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
注解管理事务以上都是xml配置的事务,基于注解的事务,只需配置<tx:annotation-driven/>标签,然后在Spring bean中添加@Transational注解即可实现事务管理。
二,Spring事务管理本质
Spring并不直接管理事务,而是提供多种事务管理器,他们讲事务管理的职责委托给JAT或其他持久化机制所提供的平台相关的事务实现。上述配置文件中就是利用的Hibernate事务管理器实现的Hibernate事务管理。详细信息不说,想事务属性什么的,具体可参考spring in action及spring官方文档
三、继续说下事务对getCurrentSession的影响
在Spring实战篇系列----源码解析SessionFactory及Session的管理及getCurrentSession的使用文章中说了getCurrentSession是要基于事务的,才能实现session的生命周期的管理。那么Spring的事务管理到底做了什么。
首先看事务管理器HibernateTransactionManager,它并没有做太多工作,一个空的构造函数及
/*** Create a new HibernateTransactionManager instance.* A SessionFactory has to be set to be able to use it.* @see #setSessionFactory*/public HibernateTransactionManager() {}
及afterPropertiesSet()方法
@Overridepublic void afterPropertiesSet() {if (getSessionFactory() == null) {throw new IllegalArgumentException("Property 'sessionFactory' is required");}if (this.entityInterceptor instanceof String && this.beanFactory == null) {throw new IllegalArgumentException("Property 'beanFactory' is required for 'entityInterceptorBeanName'");}// Check for SessionFactory's DataSource.if (this.autodetectDataSource && getDataSource() == null) {DataSource sfds = SessionFactoryUtils.getDataSource(getSessionFactory());if (sfds != null) {// Use the SessionFactory's DataSource for exposing transactions to JDBC code.if (logger.isInfoEnabled()) {logger.info("Using DataSource [" + sfds +"] of Hibernate SessionFactory for HibernateTransactionManager");}setDataSource(sfds);}}}
可见事务管理器的初始化并没有做太多工作。那么看事务管理对其的影响,先看调用栈
TransactionSynchronizationManager.initSynchronization() line: 269
HibernateTransactionManager(AbstractPlatformTransactionManager).prepareSynchronization(DefaultTransactionStatus, TransactionDefinition) line: 542
HibernateTransactionManager(AbstractPlatformTransactionManager).prepareTransactionStatus(TransactionDefinition, Object, boolean, boolean, boolean, Object) line: 513
HibernateTransactionManager(AbstractPlatformTransactionManager).getTransaction(TransactionDefinition) line: 393
TransactionInterceptor(TransactionAspectSupport).createTransactionIfNecessary(PlatformTransactionManager, TransactionAttribute, String) line: 426
TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 275
TransactionInterceptor.invoke(MethodInvocation) line: 96
ReflectiveMethodInvocation.proceed() line: 179
ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92
ReflectiveMethodInvocation.proceed() line: 179
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213
$Proxy316.getOrderById(String) line: not available
OrderController.orderPay(String, Model) line: 84
从调用栈可以看出,只要在连接点处配置了事务管理,首先都会走到initSynchronization()。
/*** Activate transaction synchronization for the current thread.* Called by a transaction manager on transaction begin.* @throws IllegalStateException if synchronization is already active*/public static void initSynchronization() throws IllegalStateException {if (isSynchronizationActive()) {throw new IllegalStateException("Cannot activate transaction synchronization - already active");}logger.trace("Initializing transaction synchronization");synchronizations.set(new LinkedHashSet<TransactionSynchronization>());}
最终会在synchronizations中set进new LinkedHashSet<TransactionSynchronization>(),从而isSynchronizationActive()为true
/*** Return if transaction synchronization is active for the current thread.* Can be called before register to avoid unnecessary instance creation.* @see #registerSynchronization*/public static boolean isSynchronizationActive() {return (synchronizations.get() != null);}
因此这里也就解释了上上篇留下的疑问,为什么配置了事务管理,就不会抛异常了。其实只有配置了事务,session就会在事务提交或者回滚后关闭
SessionImpl.close() line: 402
SessionFactoryUtils.closeSession(Session) line: 167
SpringSessionSynchronization.afterCompletion(int) line: 138
TransactionSynchronizationUtils.invokeAfterCompletion(List<TransactionSynchronization>, int) line: 168
HibernateTransactionManager(AbstractPlatformTransactionManager).invokeAfterCompletion(List<TransactionSynchronization>, int) line: 1001
HibernateTransactionManager(AbstractPlatformTransactionManager).triggerAfterCompletion(DefaultTransactionStatus, int) line: 976
HibernateTransactionManager(AbstractPlatformTransactionManager).processCommit(DefaultTransactionStatus) line: 806
HibernateTransactionManager(AbstractPlatformTransactionManager).commit(TransactionStatus) line: 730
TransactionInterceptor(TransactionAspectSupport).commitTransactionAfterReturning(TransactionAspectSupport$TransactionInfo) line: 483
TransactionInterceptor(TransactionAspectSupport).invokeWithinTransaction(Method, Class<?>, InvocationCallback) line: 290
TransactionInterceptor.invoke(MethodInvocation) line: 96
ReflectiveMethodInvocation.proceed() line: 179
ExposeInvocationInterceptor.invoke(MethodInvocation) line: 92
ReflectiveMethodInvocation.proceed() line: 179
JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 213
$Proxy316.getOrderById(String) line: not available
OrderController.orderPayInfo(String, Model) line: 72
【Spring实战】----Spring事务管理配置解析相关推荐
- spring声明式事务管理方式( 基于tx和aop名字空间的xml配置+@Transactional注解)
1. 声明式事务管理分类 声明式事务管理也有两种常用的方式, 一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解. 显然基于注解的方式更简单易用,更清爽. ...
- Spring声明式事务管理、事务的传播行为xml配置
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. <tx:method name="insert*" propagat ...
- spring,mybatis事务管理配置与@Transactional注解使用[转]
spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至 ...
- 项目中spring事务管理配置分析与修改方案
概要: 现有spring事务管理配置存在问题:对数据库无关的service层方法,也会进行事务管理(创建数据库链接.提交(回滚)事务.释放连接等),消耗资源. 修改方案:只对执行数据库写操作的serv ...
- spring,mybatis事务管理配置与@Transactional注解使用
spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性. Spring Framewor ...
- spring事务管理配置
<!-- 事务管理配置 --><bean name="transactionManager" class="org.springframework.jd ...
- Spring中的事务管理详解
在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...
- spring事务管理器的作用_【面试必问】Spring中的事务管理详解
在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...
- 【Spring学习笔记 九】Spring声明式事务管理实现机制
什么是事务?事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用,关乎数据准确性的地方我们一定要用到事务,防止业务逻辑出错. 什么是事务管理,事务管理对于企业应用而言至 ...
最新文章
- 英语口语(5月31日)
- vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- linux6.5 查看分辨率命令,centos6.5跟centos7的top命令中移动查看顺序的指令怎么不一样...
- 34 SD配置-销售凭证设置-定义销售凭证类型
- 03_Influxdb数据库的简单操作
- hive+python数据分析入门
- LeetCode 57. 插入区间(python、c++)
- openvas-tutorial-for-beginners
- Percona XtraBackup 2.0.3 发布
- MEncoder的基础用法—6.7. 媒体流复制
- 关于C++编写com和调用com组件的小例子以及个人所犯错误见解
- Ubuntu改坏sudoers后无法使用sudo的解决办法
- 【异常】java.lang.NoClassDefFoundError: com/lowagie/text/pdf/PdfContentByte
- 2013年锦绣中华民俗村迷情聊斋夜
- 靶机渗透练习06-driftingblues6 (利用脏牛提权)
- 《禅者的初心》读书笔记(1)
- 两篇关于区块链的最新综述论文被 IEEE ACCESS 接收
- 史上最详细How to Use Time Information Effectively Combining with Time Shift Module for Lipreading文章记录
- 做电商直播绝不能忽视的事:主播人设和账号定位
- 多角度解读新兴公链Sui:团队、架构、代币、生态等
热门文章
- 深入浅出业务幂等性---4、消息幂等
- echarts系列-带图教你调整左右位置x轴样式网格虚线刻度居中双轴Y轴滚动上下移动文字旋转改分割线颜色部分字体改色折注混合,X轴的颜色,X轴字体颜色,调整柱子颜色,调整小图标图例的大小和位置,鼠标
- VScode使用指南之如何全屏和退出全屏(1)
- 封装好的散点图拟合八大函数回归模型(逆、幂函、对数、S、复合、生长、指数 、线性函数,)
- hadoop完全分布+hive数据分析
- metaball公式_Houdini 节点解释
- 史上最牛实习生爆料:我在赶集网的两个月
- (改进GM(1,1)模型)灰色残差马尔科夫预测模型的matlab实现
- Python学习 —— open()函数
- 少儿机器人编程学习指南