事务传播行为种类
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,
它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
事务传播行为类型 |
说明 |
PROPAGATION_REQUIRED |
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS |
支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY |
使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW |
新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED |
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER |
以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED |
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |
ibatis spring 事务实现
1.配置动态数据源-根据KEY路由
<bean id="dataSource" class="com.xiao.AbstractRoutingDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="db2" value-ref="ds-db2" /> <entry key="sqlserver" value-ref="ds-sql" /> </map> </property> <property name="defaultTargetDataSource" ref="ds-db2" /> </bean>
2.配置事务
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED" rollback-for="Throwable" /> <tx:method name="delete*" propagation="REQUIRED" rollback-for="Throwable" /> <tx:method name="update*" propagation="REQUIRED" rollback-for="Throwable" /> <tx:method name="toggle*" propagation="REQUIRED" rollback-for="Throwable" /> <tx:method name="query*" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="servicePointcut" expression="execution(* com.xiao..*ServiceImpl.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" /> <!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="otherPointcut" /> --> </aop:config>
3.配置IBATIS
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocations"> <list> <value>classpath:/com/xiao/sqlmap-config.xml</value> </list> </property> <property name="dataSource" ref="dataSource" /> <property name="lobHandler" ref="lobHandler" /> </bean>
4.注解事务配置
XML加上 <tx:annotation-driven transaction-manager="transactionManager"/>
在实现类加上这个
@Transactional(propagation=Propagation.NOT_SUPPORTED,rollbackFor=RuntimeException.class)
问题:事务方法中,多个DAO的连接用的应该是同一个connection,SPRING是如何让sqlMapClient的connection和
transactionManager中一致的呢?
分析:可以看到它们用到的是同一个数据源。在SqlMapClientFactoryBean.afterPropertiesSet中会将datasource封装成
TransactionAwareDataSourceProxy一个代理。代理了getConnection方法。
实现细节见DataSourceUtils.doGetConnection ,该方法从当前线程中取线程本地数据(ThreadLocal)MAP,key为数据源,
值为连接,这个如果是事务中,事务的AOP会在进入事务方法前放入这个连接。所以取的连接是同一个。
问题:事务中切换动态数据源切换没用?
分析:根据上面分析,取连接时取的是进入事务方法前设置的连接,所以不行。AbstractRoutingDataSource实际是getConnection
方法动态切换数据源,但这个方法被代理了。而XML配置的DAO和事务的数据源是同一个。
事务分析:
TransactionInterceptor拦截事务方法,第一次进入,当前线程对应的ConnectionHolder为空,
调用doBegin方法,生成一个新的数据库连接ConnectionHolder,事务Transact类设置为newConnectionHolder
属性为TRUE,标记这个Transact为第一次,如果是第一次的Transact,绑定ConnectionHolder,到线程本地上下文
中,如果事务方法中还是嵌套事务情况,假设传播级别是PROPAGATION_REQUIRED(用以前的事务),进入嵌套事务方法时,连接取的
还是第一次的ConnectionHolder,但Transact类设置为newTransaction false(用来区分事务是否要提交);
Propagation.NOT_SUPPORTED:会将之前的事务挂起,当前线程的连接清空;NOT_SUPPORTED方法里的后续的SQL会直接提交,如果前后操作的SQL是同一条数据,
会引起死锁,前面的事务锁住了数据,后续事务无法提交。
Propagation.REQUIRES_NEW:会将之前的事务挂起,新建一个事务,当前线程的连接设置成新事务的数据库连接;新事务提交后,恢复之前的事务,当前线程的数据库连接
设置成恢复事务的连接。保证第一个事务的SQL用的是同一个连接。
相关推荐
spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务的底层实现流程图 spring事务...
spring事务管理几种方式代码实例:涉及编程式事务,声明式事务之拦截器代理方式、AOP切面通知方式、AspectJ注解方式,通过不同方式实例代码展现,总结spring事务管理的一般规律,从宏观上加深理解spring事务管理特性...
Spring事务管理Demo
Spring事务原理、Spring事务配置的五种方式
Spring2.5实现事务管理(本地事务、分布式事务).doc
演示了spring编程式事务的实现,通过TransactionTemplate模板进行事务控制
3、了解Spring事务管理的3个核心接口; 4、了解Spring事务管理的两种方式; 5、掌握基于XML和Annotation的声明式事务管理的使用。 二.实验内容 (1)使用Spring JDBC实现书店的购书过程,即有如下一个BookShopDao接口...
演示了spring基于AOP代理TransactionProxyFactoryBean实现事务
JOTM使用包 博文链接:https://log-cd.iteye.com/blog/807607
声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。spring注解事务实现demo
spring事务以及分布式事务实现.zip one-data-source 单数据源事务 two-data-source 多数据源事务 模块包括 多数据源配置方法 使用atomikos管理多数据源事务 多数据源事务结合Druid数据库连接池 代码包括声明式事务和...
spring整合hibernate实现事务处理 1.spring整合hibernate实现事务处理-注解方式 2.spring整合hibernate实现事务处理-XML方式
本代码使用H2内存数据库演示spring事务使用,包括编程式事务,声明式事务@Transactional使用,自定义事务事务注解实现自定义事务管理器
spring事务操作试验 博客地址:https://blog.csdn.net/u010476739/article/details/99130972
spring通过aspectj来实现事务控制
主要带领大家深入理解Spring事务原理,Spring事务的传播属性
事务简介 二、程序举例环境搭建 o1. 创建数据表 ...三、使用 Spring 的事务注解管理事务 o1. 声明事务管理器 o2. 开启注解驱动 o3. 完整Spring配置文件 o4. 业务层 public 方法加入事务属性 o5. 测试
Spring项目,数据库用mysql,整合Mybatis,需要自己创建数据库testinnodb,以及两张表Account,int id, int account,表Log,int id ,...三种事务,手动实现事务,利用AOP实现,以及声明式事务,lib中有所有的jar。
JavaEE spring事务操作环境和基本功能搭建
主要给大家介绍了关于Spring中事务用法示例及实现原理的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧