首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

spring宣言式事务策略 aop拦截-学习笔记

2012-08-28 
spring声明式事务策略 aop拦截-学习笔记?声明式事务管理:Spring提供了声明式事务管理。是通过Spring AOP实

spring声明式事务策略 aop拦截-学习笔记

?

声明式事务管理:

Spring提供了声明式事务管理。是通过Spring AOP实现的。

Spring中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现的,由于接口是延迟实例化的,spring的在这段时间内通过拦截器,加载事务切片。原理就是这样的,可以参考JDK动态代理实例。

Spring中进行事务控制:

动态代理的一个重要特征是,它是针对接口的,所以我们的DAO要通过动态代理来让spring接管事务,就必须在dao前面抽象出一个接口,当然如果没有这样的接口,那么spring会使用CGLIB来决解问题,但这不是spring推荐的方式。

大多数spring用户选择声明式事务管理。这是最少影响应用代码的选择,因而这是和非侵入性的轻量级容器的观念是一致的。

从考虑EJB CMT和spring声明式事务管理的相似以及不同之处出发是很有益的。他们的基本方法是相似的:都可以指定事务管理到单独的方法;如果需要可以在事务上下文调用setRollbackOnly()方法。不同之处如下:

1、不像EJB CMT绑定在JTA上,spring声明式事务管理可以在任何环境下使用。只需要更改配置文件,它就可以和JDBC、JDO、Hibernate或其他的事务机制一起工作。

2、spring可以使声明式事务管理应用到普通的Java对象,不仅仅是特殊的类,如EJB。

3、spring提供声明式回滚规则:EJB诶呦地域的特征,回滚可以声明式控制,不仅仅是编程式的。

4、spring允许你通过AOP定制事务行为。如:如果需要,可以在事务回滚中插入定制的行为。也可以增加任意的通知,就像事务通知一样。使用EJB CMT,除了使用setRollbackOnly(),你没有办法能够影响容器的事务管理。

5、spring不提供高端应用服务器的跨越远程调用的事务上下文传播。如果你需要这些特征,推荐你使用EJB。然而,不要轻易使用这些特性。通常我们并不希望事务跨越远程调用。


回滚规则的概念:他们使得我们可以指定哪些异常应该发起自动回滚。我们在配置文件中,而不是Java代码中,以声明的方式指定。因此,虽然我们仍然可以编程调用TransactionStatus对象的setRollbackOnly()方法来回滚当前事务,多数时候我们可以指定规则,如MyApplicationException应用导致回滚。这有明显的优点,业务对象不需要依赖事务基础设施。例如:通常不需要引入任何Spring API,事务或其他任何东西。

EJB的默认行为是遇到系统异常(通常是运行是异常),EJB容器自动回滚事务。EJB CMT遇到应用程序异常(除了java.rmi.RemoteExcepiton外的checked异常)是不需要自动回滚事务。虽然Spring声明式事务管理沿用EJB的约定(遇到unchecked异常自动回滚事务),但是这是可以定制的。

Spring声明式事务管理的性能要胜过EJB CMT。

?

<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><!-- 配置数据库驱动 --><!-- <context:property-placeholder location="classpath:jdbc.properties"/> --><bean id="propertyConfigurer" destroy-method="close"><property name="driverClassName" value="${datasource.driverClassName}"/><property name="url" value="${datasource.url}"/><property name="username" value="${datasource.username}"/><property name="password" value="${datasource.password}"/><!-- 连接池启动是的初始值 --><property name="initialSize" value="${datasource.initialSize}"/><!-- 连接池的最大值 --><property name="maxActive" value="${datasource.maxActive}"/><!-- 最大空闲值、当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --><property name="maxIdle" value="${datasource.maxIdle}"/><!-- 最小空闲值,当空闲的连接数少于阀值时,连接池就会预申请去一些连接、以免洪峰来时来不及申请 --><property name="minIdle" value="${datasource.minIdle}"/></bean><!-- 配置hibernateSessionFactory --><bean id="sessionFactory" ref="dataSource" /><!-- <property name="mappingResources"><list><value>com/sample/domain/Person.hbm.xml</value></list></property> --><property name="mappingDirectoryLocations"><list><!-- 采用属性注入com/sample/domain包下所有hbm.xml加载进来 --><value>classpath:com/sample/admin/domain</value></list></property><property name="hibernateProperties"><value>hibernate.dialect=${hibernate.dialect}hibernate.hbm2ddl.auto=${hibernate.hbm2ddl.auto}hibernate.show_sql=${hibernate.show_sql}hibernate.format_sql=${hibernate.format_sql}hibernate.cache.use_second_level_cache=${hibernate.cache.use_second_level_cache}hibernate.cache.use_query_cache=${hibernate.cache.use_query_cache}hibernate.cache.provider_class=${hibernate.cache.provider_class}</value><!-- 另外一种写法 --><!-- <props><prop key="hibernate.dialect">${hibernate.dialect}</prop></props> --></property></bean><!-- 配置事务管理器 --><bean id="transactionManager" ref="sessionFactory" /></bean><bean id="hibernateTemplate" ref="sessionFactory" /></bean><!-- 延时加载问题解决OpenSessionInViewInterceptor 和 OpenSessionInViewFilter的配置在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛session already closed Exception --><bean name="openSessionInViewInterceptor" value="true" />  --><!-- <bean id="baseTransaction" abstract="true"><property name="transactionManager" ref="transactionManager" /><property name="proxyTargetClass" value="true"/><property name="transactionAttributes"><props><prop key="get*">PROPAGATION_NOT_SUPPORTED,readOnly</prop><prop key="find*">PROPAGATION_NOT_SUPPORTED,readOnly</prop><prop key="load*">PROPAGATION_REQUIRED,readOnly</prop><prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>  <prop key="read*">PROPAGATION_REQUIRED,readOnly</prop><prop key="save*">PROPAGATION_REQUIRED,-Exception</prop><prop key="add*">PROPAGATION_REQUIRED,-Exception</prop><prop key="create*">PROPAGATION_REQUIRED,-Exception</prop><prop key="update*">PROPAGATION_REQUIRED,-Exception</prop><prop key="modify*">PROPAGATION_REQUIRED,-Exception</prop><prop key="change*">PROPAGATION_REQUIRED,-Exception</prop><prop key="delete*">PROPAGATION_REQUIRED,-Exception</prop><prop key="remove*">PROPAGATION_REQUIRED,-Exception</prop><prop key="*">PROPAGATION_REQUIRED,-Exception</prop></props></property><property name="optimize" value="true" />  </bean> --><!-- 采用AOP拦截的方式实现事务管理 --><aop:config proxy-target-expression="execution(* com.sample.admin.service..*.*(..))"/><aop:advisor advice-ref="txAdvisor" pointcut-ref="transacationPointcut"/></aop:config><tx:advice id="txAdvisor" transaction-manager="transactionManager"><tx:attributes><tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="find*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="query*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="read*" read-only="true" propagation="NOT_SUPPORTED"/><tx:method name="load*" read-only="true" propagation="REQUIRED"/><tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="create*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="change*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="remove*" propagation="REQUIRED" rollback-for="Exception"/><tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/></tx:attributes></tx:advice><!-- 采用注解方式配置 打开 --><!-- <tx:annotation-driven transaction-manager="transactionManager" />--></beans>

热点排行