zoukankan      html  css  js  c++  java
  • Spring.NET教程(十五)——事务传播行为(基础篇)

    上篇我们学习了Spring.NET的事务机制。回顾一下,实现事务需要在方法上标记[Transaction]。在很多情况下,事务往往与业务分离。Spring.NET提供了事务代理帮我们管理这些事务,我们可以通过TransactionProxyFactoryObject使用声明式事务。在很多情况下TransactionProxyFactoryObject比ProxyFactoryObject易用,因为该类可以通过自身属性来指定事务通知和事务特性,所以不需要单独为事务通知定义对象。另外,与使用ProxyFactoryObject不同,TransactionProxyFactoryObject不要求使用方法的全名,只用普通的“短”方法名即可。同时,该类可以对方法名进行wild card matching,从而强制我们为DAO的方法使用统一命名规则。

      TransactionProxyFactoryObject的TransactionAttributes属性是用来配置的传播行为,并规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:

      PROPAGATION_REQUIRED   支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
      PROPAGATION_SUPPORTS   支持当前事务,如果当前没有事务,就以非事务方式执行。
      PROPAGATION_MANDATORY   支持当前事务,如果当前没有事务,就抛出异常。
      PROPAGATION_REQUIRES_NEW   新建事务,如果当前存在事务,把当前事务挂起。
      PROPAGATION_NOT_SUPPORTED   以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
      PROPAGATION_NEVER   以非事务方式执行,如果当前存在事务,则抛出异常。
      PROPAGATION_NESTED   如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

      PROPAGATION_REQUIRED和PROPAGATION_SUPPORTS我用的比较多,其它的很少使用。特别是PROPAGATION_REQUIRED,我绝大多数情况都使用这个行为(如,在创建,删除,修改的时候),我会在查询(获取)数据的时候设置为:PROPAGATION_REQUIRED,readOnly,声明为一个只读事务,这样有助于性能的提高。

      TransactionProxyFactoryObject的Target属性是我们要拦截的对象,一般我们设置为业务层的对象。

      实现代码:


    App.config

    <?xml version="1.0" encoding="utf-8" ?>
    <objects xmlns="http://www.springframework.net" 
             xmlns:db="http://www.springframework.net/database">
      <db:provider id="DbProvider"
                    provider="SqlServer-1.1"
                    connectionString="Server=(local);Database=SpringLesson16;Uid=sa;Pwd=;Trusted_Connection=False"/>
      
      <object id="userDao" type="Dao.UserDao, Dao">
        <property name="AdoTemplate" ref="adoTemplate"/>
      </object>
      <object id="accountDao" type="Dao.AccountDao, Dao">
        <property name="AdoTemplate" ref="adoTemplate"/>
      </object>
      <object id="userService" parent="txProxyTemplate">
        <property name="Target">
          <object type="Service.UserService, Service">
            <property name="UserDao" ref="userDao"/>
            <property name="AccountDao" ref="accountDao"/>
          </object>
        </property>
      </object>
      <object id="adoTemplate" type="Spring.Data.Core.AdoTemplate, Spring.Data">
        <property name="DbProvider" ref="DbProvider"/>
        <property name="DataReaderWrapperType" value="Spring.Data.Support.NullMappingDataReader, Spring.Data"/>
      </object>
      <!--事务管理器-->
      <object id="transactionManager"
             type="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data">
        <property name="DbProvider" ref="DbProvider"/>
      </object>
      
      <object id="txProxyTemplate" abstract="true"
                type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">
        <property name="PlatformTransactionManager" ref="transactionManager"/>
        <property name="TransactionAttributes">
          <name-values>
            <add key="Save*" value="PROPAGATION_REQUIRED"/>
            <add key="Delete*" value="PROPAGATION_REQUIRED"/>
            <add key="Get*" value="PROPAGATION_REQUIRED,readOnly"/>
          </name-values>
        </property>
      </object>
    </objects>

      在name-value节点下,key属性为Save*,意思是拦截所有以Save开头的方法,在拦截到的方法上增加PROPAGATION_REQUIRED的事务传播行为。

  • 相关阅读:
    IntelliJ IDEA生成 Serializable 序列化 UID 的快捷键
    spring boot rabbitmq 多MQ配置 自动 创建 队列 RPC
    JAVA使用并行流(ParallelStream)时要注意的一些问题
    深入浅出Stream和parallelStream
    JAVA8 十大新特性详解
    redis客户端连接,最大连接数查询与设置
    如何在Java 8中愉快地处理日期和时间
    Jenkins:使用Git Parameter插件实现tag或分支的选择性构建
    Java正确获取客户端真实IP方法整理
    redis问题接囧办法及经验
  • 原文地址:https://www.cnblogs.com/millen/p/1635979.html
Copyright © 2011-2022 走看看