在理解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,创建方法也各不相同。下列常用两个。
<!-- 配置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>
<!-- 配置数据源--> <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”这个概念来自Spring1.2对AOP的支持,在AspectJ中是没有等价的概念。 advisor就像一个小的自包含的切面,这个切面只有一个通知。 切面自身通过一个bean表示,并且必须实现一个通知接口。
Spring 2.0 通过 <aop:advisor>
元素来支持advisor 概念。它大多数情况下会和transactional advice一起使用,transactional advice在Spring 2.0中有自己的命名空间。
<tx:advice/>标签只接受<tx:attributes />标签作为其子元素。
凭借<tx:attributes />标签我们可以用更加简练的方式创建transactionAttributes属性表达式。
<tx:attributes />标签只接受<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’ |
如果存在一个事务,则支持当前事务。如果没有事务则开启
如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行
如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
总是非事务地执行,并挂起任何存在的事务。
总是非事务地执行,如果存在一个活动事务,则抛出异常
如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读。
保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。