`
z_xiaofei168
  • 浏览: 197836 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

开源框架spring详解-----事务管理的深刻理解

阅读更多

spring事务管理

author:z_xiaofei168

      6.1spring的事务管理器

 

Spring框架并没有直接管理用户的应用系统中的事务,它只是提供许多供用户选择的事务管理器,然后将事务管理的责任委托给与此事务管理器对应的持久化技术的事务实现。 

 

事务管理实现

使用时机

org.springframework.jdbc.datasource.

DataSourceTransactionManager

在单一的JDBC DataSource中管理事务

org.springframework.orm.hibernate3.

HibernateTransactionManager

当持久化机制是Hibernate时,用它来管理职务

org.springframework.orm.

jpa.JpaTransactionManager

JPA用作持久化时,用它来管理职务

org.springframework.transaction.

jta.JtaTransactionManager

使用一个JTA实现来管理事务。在一个事务跨越多个资源时必须使用

 

配置文件中的配置如下:

 

<bean id=”transactionManager” class=” org.springframework.jdbc.datasource. DataSourceTransactionManager”>

                   <property name=”dataSource” ref=” dataSource”/>

</bean>

 

         6.2、事务属性介绍

 

         1>.传播行为

 

传播行为

说明

PROPAGATION_REQUIRED

必须在一个事务中执行。如果当前有一个事务正在进行,该方法将会在那个事务中执行。否则要开始一个新事务。Spring事务传播行为的默认值。

PROPAGATION_SUPPORTS

支持现有的事务。如果当前没有事务在进行,就以非事务的方式执行

PROPAGATION_MANDATORY

方法必须在一个现有事务中进行,否则会抛出异常。

PROPAGATION_REQUIRES_NEW

必须在它自己的新启事务里进行。如果现有事务在进行就先暂停它

PROPAGATION_NOT_SUPPORTED

不应在事务中进行。如果现有事务在进行就先暂停它

PROPAGATION_NEVER

不应在事务中进行。如果现有事务在进行就抛出异常

PROPAGATION_NESTED

如果现有事务正在进行,则该方法运行在一个嵌套式事务中。否则PROPAGATION_REQUIRED执行

 

         2>.隔离级别

 

 

隔离级别

说明

ISOLATION_DEFAULT

使用底层数据库默认的隔离级别spring事务隔离级别的默认值

ISOLATION_READ_UNCOMMITED

充许另一个事务可以读到这个事务未提交的数据可能导致脏读、不可重复读和幻读。

ISOLATION_READ_COMMITED

保证一个事务修改的数据提交后才能被另一个事务读取可能导致不可重复读和幻读。

ISOLATION_REPEATABLE_READ

要求对相同字段的多次读取的结果必须相同,除非事务本身更新了数据可能导致幻读。

ISOLATION_SERIALIZABLE

事务被处理为顺序执行可以防止脏读、不可重复读、幻读。

 

         3>.只读提示

 

         如果事务只对后端数据进行读操作,则后端数据库可以采用一些优化措施来提高执行效率。但必须在事务中才有效。也就是说要搭配传播行为PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_NESTED 来设置。

 

         4>.事务超时间隔

 

         还可以设置事务的超时间隔,让事务在特定秒数后自动回滚,不必等它自己结束。由于计时是从事事务开始时算起的,所以它也得搭配传播行为为 PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_NESTED 来设置。

 

         5>.回滚规则

 

         当事务运行过程中抛出异常时,事务可以被声明为回滚或者不回滚。默认情况下只在出现RuntimeExceptio才会回滚,而在出现受检异常时不回滚。

         当然,也可以改变这种回滚规则,可以声明一个事务在出现特定的受检异常时能回滚。也可以声明一个事务在出现特定的非受检异常时不回滚。

 

      6.3、声明式事务管理

 

          1>.基于xml配置方式

 

                   1步:定义事务通知

 

 

      第2部:把事务通知绑定到切入点

 

<?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:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	
	<!-- 配置不带连接池的数据源 -->
	<bean id="dataSource" 
	      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql:///spring" />
  		<property name="username" value="root" />
  		<property name="password" value="123" />
	</bean>
	
	<!-- JDBC事务管理器 -->
	<bean id="transactionManager" 
	    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	    <!-- DataSource事务管理器需要数据源实例 -->
	    <property name="dataSource" ref="dataSource"/>
	</bean>
	
	<!-- 第1步:定义事务通知(主要是针对指定事务管理器对应的事务实现配置事务参数) -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
	    	<!-- 对选定的方法配置详细的事务属性 -->
	    	<tx:method name="find*" read-only="true" />
	    	<tx:method name="*"/>
	  	</tx:attributes>
	</tx:advice>
	
	<!--  第2步:AOP配置 -->
	<aop:config>
		<!--  声明事务切入点(配置哪些类的哪些方法参与事务) --> 
		<aop:pointcut id="AllServiceMethod" 
	            expression="execution(* com.zxf.service.*.*(..))" /> 
	  	<!-- 通知器(把事务通知绑定到切入点) -->
		<aop:advisor pointcut-ref="AllServiceMethod" advice-ref="txAdvice" /> 
	</aop:config>
	
	
	<!-- 以下是Spring容器管理的Bean -->
	<bean id="accountDao" class="com.zxf.dao.AccountDaoJDBCImpl">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<bean id="accountService" class="com.zxf.service.AccountService">
		<property name="accountDao" ref="accountDao"/>
	</bean>
	
	<!-- Hibernate事务管理器
	<bean id="txManager2"   
	     class="org.springframework.orm.hibernate3.HibernateTransactionManager">
	    <property name="sessionFactory" ref ="sessionFactory"/>
	</bean>
	--> 
	<!-- JPA事务管理器
	<bean id="txManager3"   
	     class="org.springframework.orm.jpa.JpaTransactionManager">
	    <property name="entityManagerFactory" ref ="entityManagerFactory"/>
	</bean>
	--> 
</beans>

 

 

   2>.基于注解方式

      1步:在spring配置文件中启用对AspectJ注解的支持

 

 

<?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:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	
	<!-- 配置不带连接池的数据源 -->
	<bean id="dataSource" 
	      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql:///spring_04" />
  		<property name="username" value="root" />
  		<property name="password" value="root" />
	</bean>
	
	<!-- JDBC事务管理器 -->
	<bean id="transactionManager" 
	    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	    <!-- DataSource事务管理器需要数据源实例 -->
	    <property name="dataSource" ref="dataSource"/>
	</bean>
	<!-- 启用对事务注解的支持  -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
	
	
	<!-- 以下是Spring容器管理的Bean -->
	<bean id="accountDao" class="com.zxf.dao.AccountDaoJDBCImpl">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<bean id="accountServiceByTxAnnotation" 
		  class="com.zxf.service.AccountServiceByTxAnnotation">
		<property name="accountDao" ref="accountDao"/>
	</bean>
</beans>

 

    2步:用@Transactional注解指定接口、类或方法的事务属性

 

package com.zxf.service;

import java.util.List;
import org.springframework.transaction.annotation.Transactional;

import com.zxf.dao.AccountDao;
import com.zxf.domain.Account;

/** Account业务逻辑类--基于注解方式的声明式事务管理配置 */
@Transactional //指定需要声明式事务,事务属性使用默认值
public class AccountServiceByTxAnnotation {
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao){
		this.accountDao = accountDao;
	}
}

 

 

 

17
11
分享到:
评论
6 楼 javamanlcy007 2011-05-30  
skycray 写道
怎么设定特别exception的事务回滚???

@Transactional(readOnly = false, rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
5 楼 skycray 2011-05-25  
怎么设定特别exception的事务回滚???
4 楼 z_xiaofei168 2011-05-23  
wutao8818 写道
不错,简单明了。

共同学习,呵呵
3 楼 wutao8818 2011-05-23  
不错,简单明了。
2 楼 z_xiaofei168 2011-05-16  
呵呵,那你可以试试啊,试试就知道了,你说呢??
1 楼 rancococ 2011-05-16  
楼主:
<tx:method name="find*" read-only="true" />  这么设置的时候,find*方法中如果有更新的操作同样可以进行,你测试过没?

相关推荐

Global site tag (gtag.js) - Google Analytics