Spring事务管理

本文介绍了Spring框架中的三种事务管理方式:使用Spring的事务代理工厂、使用Spring的事务注解以及使用AspectJ的AOP配置。文章详细阐述了每种方式的具体配置步骤及使用场景,并对AOP相关术语进行了说明。

一、Spring对事务的管理方式

Spring通常使用以下三种方式实现对事务的管理
    1、使用Spring的 事务代理工厂 管理事务;
    2、使用Spring的 事务注解 管理事务;
    3、使用 AspectJ的AOP 配置管理事务。
    
二、Spring事务管理API
    Spring的事务管理,主要用到两个事务相关的接口。
    1、事务管理器接口
        事务管理器是 PlatformTransactionManager 接口对象。主要用于完成事务的提交、回滚 以及获取事务的状态信息。
        A、常用的两个实现类:
            PlatformTransactionManager 接口有两个常用的实现类:
                DataSourceTransactionManager : 使用JDBC或iBatis进行持久化数据时使用;
                HibernateTransactionManager : 使用Hibernate 进行持久化数据时使用。
        B、Spring的回滚方式
            Spring事务的默认回滚方式是:发生运行时异常时回滚,发生受查异常时提交,不过,对于受查异常,也可以手工设置其回滚方式。
    2、事务定义接口:
        事务定义接口 TransactionDefinition 中定义了事务描述相关的三类常量:
            事务隔离级别、事务传播行为、事务默认超时时限、以及对他们的操作。
            


三、Demo

    事务一般多用于对数据库的操作,所以想配置好数据库文件,当前以SpringMVC项目,IDE是eclipse。

jdbc.properties 中配置数据库的连接,每种数据库连接的驱动不一样,这里是MYSQL。

# MySQL 
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mytestdb?useUnicode=true&characterEncoding=gbk
jdbc.username=root
jdbc.password=root

 

使用的spring-config.xml文件中用到的xsd约束如下图:

配置好后在spring-config.xml中添加加载jdbc.properties文件的配置,添加数据源配置,

     <!-- 注册JDBC属性文件 -->
     <context:property-placeholder location="classpath:jdbc.properties"/>

     <!-- 注册数据源 -->

     <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

案例一、使用 Spring的事务代理工厂管理事务:
    事务代理使用的类是 TransactionProxyFactoryBean ,该类需要初始化如下一些属性:
        transactionManager : 事务管理器
        target : 目标对象,即Service实现类对象
        transactionAttributes : 事务属性设置
        
    对于XML配置代理方式实现事务管理时,受查异常的回滚方式,程序员可以通过以下方式进行设置。
    通过“-异常”方式,可使发生指定的异常时事务回滚;通过“+异常”方式,可使发生指定的异常时事务提交。

这个方法管理事务配置比较繁琐。

spring-cpnfig.xml文件中注册dao和service的bean对象,添加代理事务的配置

     <!-- 注册Dao -->
     <bean id="accountDao" class="com.transaction.dao.impl.AccountDaoImpl">
         <property name="dataSource" ref="myDataSource"/>
     </bean>
     <bean id="stockDao" class="com.transaction.dao.impl.StockDaoImpl">
         <property name="dataSource" ref="myDataSource"/>
     </bean>
     <!-- 注册Service -->
     <bean id="stockService" class="com.transaction.service.StockProcessServiceImpl">
         <property name="accountDao" ref="accountDao"/>
         <property name="stockDao" ref="stockDao"/>
     </bean>  

     <!-- 注册事务管理器,三种管理方式都需要事务管理器 -->

     <bean id="myTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="myDataSource"/>
     </bean>

     <!-- 生成事务代理   用事务代理工厂处理事务-->

     <bean id="stockServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
         <property name="transactionManager" ref="myTxManager"/>
         <property name="target" ref="stockService"/>
         <property name="transactionAttributes">
             <props>

                 <!-- key值service中要使用事务的方法名或其正则,中间就是事务的隔离级别和传播级别-->
                 <prop key="open*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
                 <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-StockException</prop>
             </props>
         </property>
     </bean>

此时使用 事务代理工厂管理事务配置完成,使用stockServiceProxy实例调用open开头的方法和buyStock方法会有事务管理,出现异常会事务回滚,代码在后面打包,稍安勿躁。

 

案例二、使用 SpringAOP 注解管理事务

说白了这个是直接在对应方法上添加事务注解 @Transactional(isolation=Isolation.DEFAULT, propagation=Propagation.REQUIRED)

这个方法配置简单,但是如果添加事务的方法太多的话,不太好管理。

并且配置隔离级别和传播级别。

现在先在spring-config.xml中添加事务配置,开启SpringAOP事务

     <!-- 注册事务管理器 -->
     <bean id="myTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="myDataSource"/>
     </bean>

    <!-- 开启注解驱动  可以使用SpringAOP设置事务 -->
    <tx:annotation-driven transaction-manager="myTxManager"/> 

如此便是配置好了SpringAOP事务配置,下面就是在方法中使用注解例子

 

案例三、使用 Spring AspectJ 管理事务

基于AspectJ配置文件,同一在一个地方配置事务,不会担心哪个需要配置事务的地方被漏掉。

下面就是spring-config.xml中的配置

     <!-- 事务 -->
     <!-- 注册事务管理器 -->
     <bean id="myTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
         <property name="dataSource" ref="myDataSource"/>
     </bean>

    <!-- 使用AspectJ 设置事务 -->
    <!-- 注册事务通知 -->
     <tx:advice id="txAdvice" transaction-manager="myTxManager" >
        <tx:attributes>
        <!-- 
       propagation    :事物传播行为
        isolation   :事物隔离级别
        read-only   :只读
        rollback-for    :发生哪些异常回滚
        no-rollback-for    :发生哪些异常不回滚
        timeout    :过期信息
       -->
            <!-- 指定在连接点方法上应用的事务属性 -->
            <tx:method name="open*" isolation="DEFAULT" propagation="REQUIRED" />
            <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="StockException" />
        </tx:attributes>
    </tx:advice>
    <!-- AOP配置 -->
    <aop:config>
        <!-- 指定切入点 -->
        <aop:pointcut id="stockPointCut" expression="execution(* com.transaction.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="stockPointCut" />
    </aop:config>

配置完成,这个其实还可以直接开启注解模式,使用注解来使用Aspect管理事务。

    <!-- 开启aop 使用AspectJ去管理事务 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

四、AOP相关术语
    通知:通知定义了切面是什么时候以及何时使用的概念,Spring切面有五类通知
            前置通知(Before):在目标方法被调用之前调用通知功能。
            后置通知(After):在目标方法完成之后调用通知,此时不关心方法的输出结果。
            返回通知(After-returning):在目标方法成功执行之后调用通知。
            异常通知(After-throwing):在目标方法抛出异常之后调用通知。
            环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
            
    连接点:是在应用执行过程中能够插入切面的一个点。
    切点:切点定义了切面在何处要织入一个或者多个连接点。
    切面:是通知和切点的结合,通知和切点共同定义了切面的全部内容。
    引入:引入允许我们向现有类添加新方法或属性。
    织入:是把切面应用到目标对象,并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。在目标对象的生命周期中有多个点可以进行织入:
            编译期:在目标类编译时,切面被织入。这种方式需要特殊的编译器,AspectJ的织入编译器就是以这种方式织入切面的。
            类加载期:切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(class loader)它可以在目标类呗引入应用之前增强该目标类的字节码。
            运行期:切面在应用运行到某个时刻时被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态地创建一个代理对象。SpringAOP就是以这种方式织入切面的。

 

项目地址: https://github.com/helloX007/springtransaction.git

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值