zoukankan      html  css  js  c++  java
  • Sping中的事务配置

    关于Spring的事务配置,主要的配置文件如下(使用了C3P0连接池):

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
           <!--导入外部文件资源-->
           <context:property-placeholder location="classpath:db.properties"/>
           <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                  <property name="user" value="${jdbc.user}"/>
                  <property name="password" value="${jdbc.password}"/>
                  <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
                  <property name="driverClass" value="${jdbc.driverClass}"/>
                  <property name="initialPoolSize" value="${jdbc.initPoolSize}"/>
                  <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
           </bean>
           <!--声明事务管理器-->
           <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                  <property name="dataSource" ref="dataSource"/>
           </bean>
           <!--声明事务通知(相当于切面)-->
           <tx:advice id="notifier" transaction-manager="txManager">
           </tx:advice>
           <!--声明事务通知需要通知的方法-->
           <aop:config>
                  <aop:pointcut id="cutId" expression="execution(* *.*(..))"/>
                  <aop:advisor advice-ref="notifier" pointcut-ref="cutId"/>
           </aop:config>
    </beans>
    

    除了在XNL文件中配置事务,而且还可以使用@Transaction注解声明式地管理任务,Spring允许使用@Transaction注解来标注事务方法(只能标注公有方法,因为AOP是基于代理机制的)

    也可以将@Transaction注解标注在类级别上,那么类中所有的公共方法都会被定义成支持事务处理的。另外为了支持@Transaction注解,还需要在配置文件中启用<tx:annotion-driven>元素,并为之指定事务管理器,如果事务管理器的名字是transactionManager的话,可以省略。

           <context:component-scan base-package="*"/>
           <tx:annotation-driven transaction-manager="txManager"/>
    

    事务的传播属性

         当事务方法被另一个事务方法调用时,必须指定事务应该如何传播,例如,方法可能继续在现有的事务中运行,也可能开启一个新的事务,并在自己的事务中运行。

    Spring制订了7中类型的传播行为:

          -REQUIRED   如果有事务在运行,当前的方法就在该事务中运行,否则,就启动一个新的事务,并在自己的事务中运行

         -REQUIRED_NEW  必须启动新事务,并在新的事务中运行,并将之前的事务挂起

         -SUPPORT    如果有事务在运行,当前方法在这个事务内运行,如果没有,该方法就不在事务中运行

         -NOT_SUPPORT  当前的方法不在事务中运行,如果有运行的事务,它将挂起

         -MANDATORY   当前方法必须运行在事务内部,如果没有运行的事务,就抛出异常

         -NEVER   当前的方法不运行在事务中,如果有运行的事务,就抛出异常

         -NESTED   如果有事务在运行,当前的方法就应该在这个事务的嵌套事务内运行,否则,就启动一个事务,并在自己的事务中运行

    如下代码:

           <!--声明事务通知(相当于切面)-->
           <tx:advice id="notifier" transaction-manager="txManager">
                  <tx:attributes>
                         <tx:method name="methodName" propagation="REQUIRES_NEW"/>
                  </tx:attributes>
           </tx:advice>
    

    事务的隔离级别:

          从理论上讲,各个事务之间是完全彼此隔离的,以避免并发事务所导致的问题,在实际开发中为了提升性能,事务会以较低的隔离级别运行,事务的隔离级别可以通过隔离事务属性指定

    四个事务隔离级别:

        DEFAULT:使用底层数据库默认的隔离级别,大多数数据库的默认隔离级别是READ_COMMITED

        READ_UNCOMMITTED:允许事务读取未被其它事务提交的变更,脏读,不可重复读和幻读等问题都会出现

        READ_COMMITED:只允许事务读取已经被其它事务提交过的变更,可避免脏读,但不可重复读和幻读的问题仍会出现

        REPETABLE_READ:确保事务可以从一个字段中读取相同的值,在这个事务的持续期间,禁止其它事务对这个字段进行更新,可以避免脏读和不可重复读,但是幻读的问题仍存在

        SERIALIZABLE:确保事务可以从一个表中读取相同的行,在这个事务的持续期间,禁止其它事务对这个表执行输入,更新和删除操作,所有并发问题都可避免,但是性能十分低下。

    事务的隔离级别要得到底层数据库引擎的支持,而不是应用框架的支持。

           <!--声明事务通知(相当于切面)-->
           <tx:advice id="notifier" transaction-manager="txManager">
                  <tx:attributes>
                         <tx:method name="methodName" propagation="REQUIRES_NEW" isolation="READ_COMMITTED"/>
                  </tx:attributes>
           </tx:advice>
    

    设置回滚事务属性:

           <tx:advice id="txRoll" transaction-manager="txManager">
                  <tx:attributes>
                         <!--
                              rollbackFor:遇到时必须进行回滚
                              noRollbackFor:一组异常类,遇到时不必回滚
                              上面两个属性的值都是一组异常类,如果有多个异常类,可用逗号或空格分开
                         -->
                         <tx:method name="methodName" propagation="REQUIRES_NEW" isolation="READ_COMMITTED"
                                    rollback-for="java.io.IOException,java.sql.SQLTransientException"
                                    no-rollback-for="java.lang.RuntimeException"/>
                  </tx:attributes>
           </tx:advice>
    

    超时和只读属性:

          超时属性:事务在回滚之前可以保持多久,这样可以防止长期运行的事务占用资源

          只读属性:表示这个事务只读取数据但是不更新数据,这可帮助数据库引擎优化事务

           <tx:advice id="txRoll" transaction-manager="txManager">
                  <tx:attributes>
                         <!--
                              rollbackFor:遇到时必须进行回滚
                              noRollbackFor:一组异常类,遇到时不必回滚
                              上面两个属性的值都是一组异常类,如果有多个异常类,可用逗号或空格分开
                         -->
                         <tx:method name="methodName" propagation="REQUIRES_NEW" isolation="READ_COMMITTED"
                                    rollback-for="java.io.IOException,java.sql.SQLTransientException"
                                    no-rollback-for="java.lang.RuntimeException"
                                    timeout="30"
                                    read-only="true"
                                 />
                  </tx:attributes>
           </tx:advice>
    

      

  • 相关阅读:
    Servlet--j2e中文乱码解决
    python 通过ftplib 实现上传下载
    使用sqlyog将sql server 迁移到mysql
    c++
    二进制(signed or unsigned)补码
    sql 2012先分离迁移mdf mlf 文件到别的机器后附加 数据库成只读的修复方法
    events
    NoSQL文章
    程序员如何成功的假装在很努力的工作(转)
    如何成为强大的程序员(转)
  • 原文地址:https://www.cnblogs.com/hujingwei/p/5344802.html
Copyright © 2011-2022 走看看