`

SPRING事务实现

    博客分类:
  • java
阅读更多

事务传播行为种类

Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,

它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:

表1事务传播行为类型

事务传播行为类型

说明

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事务...

    Spring事务管理Demo

    Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...

    spring事务管理几种方式代码实例

    spring事务管理几种方式代码实例:涉及编程式事务,声明式事务之拦截器代理方式、AOP切面通知方式、AspectJ注解方式,通过不同方式实例代码展现,总结spring事务管理的一般规律,从宏观上加深理解spring事务管理特性...

    Spring分布式事务实现

    总结来说,Spring分布式事务实现主要依赖于Spring框架的事务管理能力、JOTM作为JTA实现的事务管理器,以及相关的JDBC驱动来连接数据库。通过声明式事务管理,开发者可以在不深入事务管理细节的情况下,编写出可靠的...

    spring事务与数据库操作

    ### Spring事务与数据库操作 #### 一、Spring的声明式事务管理 在现代软件开发中,事务处理是非常关键的一部分,特别是在涉及多个数据操作时。Spring框架提供了强大的事务管理能力,可以方便地集成到应用程序中。...

    Spring事务原理、Spring事务配置的五种方式

    Spring事务管理创造性的解决了很多以前要用重量级的应用服务器才能解决的事务问题,那么其实现原理一定很深奥吧?可是如果读者仔细研究了Spring事务管理的代码以后就会发现,事务管理其实也是如此简单的事情。这也...

    Spring事务流程图

    Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。在Spring中,事务管理分为编程式和声明式两种方式。本篇文章将详细解释Spring事务管理的流程,以及如何通过时序图来理解这一...

    Spring2.5实现事务管理(本地事务、分布式事务).doc

    Spring 2.5 实现事务管理(本地事务、分布式事务) Spring 框架提供了对事务管理的支持,它可以使得事务的管理变得更加简洁和灵活。事务管理是指在多个操作中维持一致性的机制,它可以确保在多个操作中,如果某个...

    Spring事务管理开发必备jar包

    在Spring框架中,事务管理是实现业务...综上所述,这个资源包涵盖了Spring事务管理开发的各个方面,从基础框架到具体实现,为开发者提供了全面的支持。理解并掌握这些知识点,将有助于构建稳定、健壮的事务处理系统。

    spring事务操作试验

    本文将深入探讨在"spring事务操作试验"中涉及的关键知识点,并结合提供的资源进行详细阐述。 首先,Spring事务管理的核心概念是ACID(原子性、一致性、隔离性和持久性),这是所有事务系统的基础。在Spring中,事务...

    spring基于AOP实现事务

    对于Spring事务管理,我们通常有两种方式:编程式和声明式。编程式事务管理需要在代码中显式地调用begin、commit、rollback等事务控制方法,而声明式事务管理则是在配置文件或注解中声明事务规则,更加简洁且易于...

    Spring事务管理失效原因汇总

    这是因为在Spring事务管理的实现中,默认情况下unchecked异常会被视作回滚异常。 除了异常外,方法的权限问题也会导致Spring事务管理失效。由于Java的继承机制,private、final、static修饰的方法不能被重写,因此...

    spring编程式事务实现

    在Spring框架中,事务管理是应用开发中的重要一环,它确保了数据的一致性和完整性。Spring提供了两种主要的事务管理方式:声明式事务管理和编程式事务管理。本篇文章将聚焦于编程式事务管理,特别是如何通过`...

    Spring事务小demo

    这个名为"Spring事务小demo"的项目提供了一个实践示例,帮助开发者了解Spring事务处理的基本概念和用法。 首先,Spring事务管理是Spring框架的核心特性之一,它允许我们以声明式或编程式的方式管理事务。声明式事务...

    spring事务案例分析.zip

    而"studyspring"可能是源代码目录,包含了实现这些案例的Java类和配置文件,通过阅读和学习这些代码,可以更深入地理解Spring事务的运用。 总结,Spring事务管理是其核心功能之一,它简化了事务处理的复杂性,使...

    Spring 事务简单完整例子

    本文将深入探讨在Spring框架中如何管理事务,以“Spring 事务简单完整例子”为出发点,结合标签“spring,事务,jdbc事务”,我们将详细解释Spring事务管理的原理和实践。 首先,Spring提供了两种事务管理方式:编程...

    Spring事务管理的jar包

    本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组操作,这些操作被视为一个整体,要么全部完成...

    SPRING事务机制DEMO

    Spring事务机制是Java开发中非常重要的一个概念,它在企业级应用中扮演着核心角色,确保数据的一致性和完整性。Spring提供了多种事务管理方式,包括编程式事务管理和声明式事务管理。在这篇DEMO中,我们将重点探讨...

    spring学习事务源码

    本文将深入探讨Spring事务管理的源码,理解其背后的实现机制。 首先,Spring事务管理有两种主要模式:编程式事务管理和声明式事务管理。编程式事务管理通过调用`PlatformTransactionManager`接口提供的方法进行显式...

    实验 spring 声明事务

    Spring 提供了声明式事务管理,允许开发者在不编写事务管理代码的情况下实现事务控制,极大地简化了事务处理。 实验环境主要包括 Eclipse 或 MyEclipse 开发工具,以及 Spring 4.0 及以上版本,JDK 1.7 及以上版本...

Global site tag (gtag.js) - Google Analytics