ITEEDU

Spring声明式事务管理简介

概述

在理解Spring的声明式事务管理方面最重要的概念是:Spring的事务管理是通过AOP代理实现的。其中的事务通知由元数据(目前基于XML或注解)驱动。代理对象与事务元数据结合产生了一个AOP代理,它使用一个PlatformTransactionManager实现品配合TransactionInterceptor,在方法调用前后实施事务。

事务语义封装在<tx:advice/>定义中,用<aop:advisor>标签在</aop:config>中施加到指定切入点(<aop:pointcut>)。

<aop:advisor>标签是</aop:config>的直接子标签,所以<aop:pointcut>也要定义在</aop:config>中。

示例:

<!-- 配置事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager=" txManager">
	<tx:attributes>
		<tx:method name="add*" propagation="REQUIRED" />
		<tx:method name="del*" propagation="REQUIRED" />
		<tx:method name="modify*" propagation="REQUIRED" />
		<tx:method name="*" read-only="true" />
	</tx:attributes>
</tx:advice>

<!-- 那些类的哪些方法参与事务 -->
<aop:config>
	<aop:pointcut id="allManagerMethod"
		expression="execution(* com.iteedu.manager.*.*(..))" />
	<aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice" />
</aop:config>

如果 PlatformTransactionManager bean的名字是 ‘transactionManager’ 的话,事务通知(<tx:advice/>)中的 ‘transaction-manager’ 属性可以忽略。否则你则需要像上例那样明确指定。

想为不同组的对象设置 完全不同 的事务语义。在Spring中,你可以通过定义各自特定的 <aop:advisor/> 元素,每个advisor采用不同的 ‘pointcut’ 和 ‘advice-ref’ 属性,来达到目的。

transaction-manager

每种框架都有自己的transaction-manager,创建方法也各不相同。下列常用两个。

hibernate

<!-- 配置sessionFactory -->
<bean id="sessionFactory"
	class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
	<property name="configLocation">
		<value>classpath:hibernate.cfg.xml</value>
	</property>
</bean>

<!-- 配置事务管理器 -->
<bean id=" txManager "
	class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	<property name="sessionFactory">
		<ref bean="sessionFactory" />
	</property>
</bean>

jdbc

<!-- 配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
	destroy-method="close">
	<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
	<property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis" />
	<property name="username" value="scott" />
	<property name="password" value="tiger" />
</bean>
<!-- 配置事务管理器 -->
<bean id="txManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

 

Advisors

“advisors”这个概念来自Spring1.2对AOP的支持,在AspectJ中是没有等价的概念。 advisor就像一个小的自包含的切面,这个切面只有一个通知。 切面自身通过一个bean表示,并且必须实现一个通知接口。

Spring 2.0 通过 <aop:advisor> 元素来支持advisor 概念。它大多数情况下会和transactional advice一起使用,transactional advice在Spring 2.0中有自己的命名空间。

<tx:advice/> 有关的设置

<tx:advice/>标签只接受<tx:attributes />标签作为其子元素。

凭借<tx:attributes />标签我们可以用更加简练的方式创建transactionAttributes属性表达式。

<tx:attributes />标签只接受<tx:method />标签作为其子元素。

<tx:method/> 有关的设置

 

属性

默认值

描述

name

与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法。 如:’get*’、’handle*’、’on*Event’等等。

propagation

REQUIRED

事务传播行为

isolation

DEFAULT

事务隔离级别

timeout

-1

事务超时的时间(以秒为单位)

read-only

false

事务是否只读?

rollback-for

将被触发进行回滚的 Exception(s);以逗号分开。 如:’MyBusinessException,ServletException’

no-rollback-for

被触发进行回滚的 Exception(s);以逗号分开。   如:’MyBusinessException,ServletException’

了解事务的几种传播特性

PROPAGATION_REQUIRED

如果存在一个事务,则支持当前事务。如果没有事务则开启

PROPAGATION_SUPPORTS

如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行

PROPAGATION_MANDATORY

如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

PROPAGATION_REQUIRES_NEW

总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

PROPAGATION_NOT_SUPPORTED

总是非事务地执行,并挂起任何存在的事务。

PROPAGATION_NEVER

总是非事务地执行,如果存在一个活动事务,则抛出异常

PROPAGATION_NESTED

如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行

Spring事务的隔离级别

ISOLATION_DEFAULT

这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.

另外四个与JDBC的隔离级别相对应

ISOLATION_READ_UNCOMMITTED

这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。

这种隔离级别会产生脏读,不可重复读和幻像读。

ISOLATION_READ_COMMITTED

保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

ISOLATION_REPEATABLE_READ

这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。

它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

ISOLATION_SERIALIZABLE

这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

除了防止脏读,不可重复读外,还避免了幻像读。