`
zhangwei_david
  • 浏览: 476979 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring 中的事务处理

阅读更多

   Spring 支持编程式事务和声明是事务处理。 编程式事务管理通过在业务方法中嵌入控制事务提交和回滚的事务管理代码来实现。 声明式事务管理时通过AOP框架支持的。

   Spring 核心事务管理抽象基于PlatformTransactionManager接口。它封装了一组用户事务管理的技术独立方法。TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

void commit(TransactionStatus status) throws TransactionException;

void rollback(TransactionStatus status) throws TransactionException;

 

Spring 对这个接口提供了多种内建实现:

JtaTransactionManager

JmsTransactionManager

JpaTransactionManager

JdoTransactionManager

HibernateTransactionManager

DataSourceTransactionManager

 

 

Spring 事务的传播属性有”

REQUIRED: 如果现有事务正在运行,当前方法应该在事务中运行,否则它将启动新的事务,并在自己的事务中运行。

REQUIRES_NEW:当前方法必须启动新事务,并在自己的事务中运行;如果现有的事务正在运行,它将被挂起。

SUPPORTS:如果现有事务重在运行,当前方法应该运行在事务中,否则它没有必要运行在事务中。

NOT_SUPPORTED:当前方法不应该运行在事务中,如果现有事务正在运行则,它将被挂起

MANDATORY:当前方法必须运行在一个事务中,如果没有事务在进行中,它将抛出一个异常;

NEVER:当前方法不应该运行在事务中,如果现有事务正在运行中,将抛出一个异常。

NESTED:如果现有事务正在运行,当前方法应该运行在嵌套事务中,否则,它应该启动一个新的事务并运行在自己的事务中。这个功能时Spring 特有的。该行为对批处理特别有用。

 

 

事务的隔离:

 事务的隔离是由底层数据库引擎实现的而不是Spring 框架实现的。

 

 DEFAULT: 使用底层数据库默认的隔离级别。对于大多数数据库而言,默认的隔离级别是READ_COMMITTED;

READ_UNCOMMITTED: 允许读取其他事务未提交的修改

READ_COMMITTED:运行读取其他事务提交的修改

REPEATABLE_READ:确保事务能够多次从一个字段中读取到同一个值。在本事务期间,其他事务更细被禁止。

SERIALIZABLE:确保一个事务从表中多次读取相同的行。在事务期间,其他事务对该表的插入,更新,删除将全部被禁止。

 

 

 

编程式事务管理:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:task="http://www.springframework.org/schema/task" 
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/jee 
		http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
		http://www.springframework.org/schema/task  
        http://www.springframework.org/schema/task/spring-task-3.1.xsd
		">
	<context:component-scan base-package="com.david.*" />
	<aop:aspectj-autoproxy />

	<!-- 定义jdbc模板类 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- 事务模板 -->
	<bean id="transactionTemlate"
		class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"/>
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" />


	<bean
		class="org.springframework.validation.beanvalidation.BeanValidationPostProcessor" />
	<!-- 方法验证后处理器 -->
	<bean
		class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor" />
</beans>

 

  /**
     * @see com.david.biz.service.BookService#addBook(com.david.common.domain.Book)
     */
    public boolean addBook(final Book book) throws Exception {
        transactionTemplate.execute(new TransactionCallback<Boolean>() {

            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    bookDao.insert(book);
                    return Boolean.TRUE;
                } catch (Exception e) {
                    // rollback
                    status.setRollbackOnly();
                }
                return Boolean.FALSE;
            }

        });
    }

 

使用声明式事务管理:

/**
     *
     * @see com.david.biz.service.BookService#addBook()
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void addBook(Book book) throws Exception {
        bookDao.insert(book);
        throw new UnRollbackException("受检查异常是不会回滚事务的");
    }

 默认情况下,只有非受控异常也就是RuntimerException 和Error类型的异常将导致事务回滚,而受控异常则不会回滚。但是可以通过设置rollbackFor 和noRollbackFor属性处理受控异常的回滚。

 

 public class AService{
	
	private BService b;
	
	@Transactional(propagation = Propagation.REQUIRED)
	public void aMethod(){
		b.bmethod();
	}
 }
 
 public class BService{
 
   @Transactional(propagation = Propagation.REQUIRED)
   public void bMethod(){
   
   }
 }

 如果事务的传播属性是REQUIRED, 如果b的事务已经提交后,在a中发生异常则会连同b一起回滚,因为这个两个使用的是同一个事务。

如果事务的传播属性是REQUIRES_NEW, 则a 中发生异常不会响应到b的事务提交,因为b和a是两个不同的是事务

 

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

	/**
	 * 指定事物限定符,用于确定目标事物管理器,匹配指定具体的PlatformTranscationManager bean定义的指定的值或名字
	 */
	String value() default "";

	/**
	 * 设置事物的传播属性,默认是REQUIRED
	 */
	Propagation propagation() default Propagation.REQUIRED;

	/**
	 *设置事物的隔离级别
	 */
	Isolation isolation() default Isolation.DEFAULT;

	/**
	 * 设置事物超时时间
	 */
	int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

	/**
	 * 如果是只读事务则设置为true,默认值是false
	 */
	boolean readOnly() default false;

	/**
	 * 定义0个或多个事务回滚的异常类型
	 */
	Class<? extends Throwable>[] rollbackFor() default {};

	/**
	 * 指定0个或多个事务回滚的异常名称
	 */
	String[] rollbackForClassName() default {};

	/**
	 * 排除不需要回滚的易异常
	 */
	Class<? extends Throwable>[] noRollbackFor() default {};

	/**
	 * 排除不需要回滚的异常名称
	 */
	String[] noRollbackForClassName() default {};

}

 

  在Spring的事务处理中是不识别@Transation 注解的,首先将@Transcation注解解析为Spring 事务系统能够识别的RuleBaseTranscationAttribute

/**
 * 解析Transcation事务注解的策略
 */
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
		Transactional ann = AnnotationUtils.getAnnotation(ae, Transactional.class);
		if (ann != null) {
			return parseTransactionAnnotation(ann);
		}
		else {
			return null;
		}
	}
	
	/**
	 * 
	 **/
	public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
		// 创建一个RuleBaseTranscationAttribute对象
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
		//将注解的事务传播属性设置到RuleBasedTranscationAttribute对象中
		rbta.setPropagationBehavior(ann.propagation().value());
		//将事务注解的事务隔离级别设置到RuleBasedTranscationAttribute对象中
		rbta.setIsolationLevel(ann.isolation().value());
		//设置事务超时时间
		rbta.setTimeout(ann.timeout());
		// 设置只读属性
		rbta.setReadOnly(ann.readOnly());
		//限定事务管理器
		rbta.setQualifier(ann.value());
		//创建事务事务会馆条件参数队列
		ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>();
		//获取事务注解中配置的回滚异常类
		Class[] rbf = ann.rollbackFor();
		// 根据配置的异常类创建RollbackRuleAttribute
		for (Class rbRule : rbf) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		// 获取事务注解配置的回滚异常名称
		String[] rbfc = ann.rollbackForClassName();
		for (String rbRule : rbfc) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//获取事务注解配置的不回滚异常类
		Class[] nrbf = ann.noRollbackFor();
		for (Class rbRule : nrbf) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//获取事务注解配置的不回滚异常名称
		String[] nrbfc = ann.noRollbackForClassName();
		for (String rbRule : nrbfc) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//设置回滚条件
		rbta.getRollbackRules().addAll(rollBackRules);
		return rbta;
	}

	// 重写equals的同时重写hashCode
	@Override
	public boolean equals(Object other) {
		return (this == other || other instanceof SpringTransactionAnnotationParser);
	}

	@Override
	public int hashCode() {
		return SpringTransactionAnnotationParser.class.hashCode();
	}

}

 

0
0
分享到:
评论

相关推荐

    Spring2.0 事务处理

    这篇博客将深入探讨Spring 2.0中的事务处理机制,以及如何通过`applicationContext.xml`配置文件来设置和管理事务。 首先,让我们理解什么是事务。事务是一组数据库操作,这些操作被视为一个单一的工作单元,要么...

    Spring声明式事务处理

    Spring框架的声明式事务处理是Java企业级应用中不可或缺的一部分,它为开发者提供了一种方便、高效的方式来管理事务。在Spring中,事务管理分为编程式和声明式两种方式,而声明式事务处理则是通过配置来控制事务的...

    aop与spring事务处理

    ### AOP与Spring事务处理详解 #### 一、引言:为什么使用框架和设计模式? 在软件开发领域,设计模式和框架是两个重要的概念。设计模式作为一种指导思想,能够帮助开发者更好地解决常见的软件设计问题,确保系统...

    Spring配置事务处理

    这是在java里使用到spring的配置文件里,添加事务处理过程,以至于可以回滚事务,当中使用到拦截器。

    Spring Hibernate 事务处理 详细说明

    在企业级Java应用开发中,事务处理是核心功能之一,确保数据的一致性和完整性。本篇文章将深入探讨Spring与Hibernate整合下的事务管理,帮助开发者理解并掌握这一关键知识点。 首先,Spring框架提供了声明式事务...

    Spring源代码解析(六):Spring声明式事务处理.doc

    Spring 中的事务处理可以分为两种方式:声明式事务处理和编程式事务处理。声明式事务处理通过 AOP 的实现,把事务管理代码作为方面封装到业务代码中,使得事务管理代码和业务代码解藕。这使得事务管理变得更加灵活...

    Spring事务管理Demo

    Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...

    Spring事务处理-ThreadLocal的使用

    本篇文章将聚焦于Spring事务处理中ThreadLocal的使用,以及如何通过源码理解和应用这个工具。 首先,了解Spring事务管理的基本概念。在多线程环境中,事务管理是至关重要的,它负责确保一组数据库操作要么全部成功...

    实验 spring 声明事务

    Spring 提供了声明式事务管理,允许开发者在不编写事务管理代码的情况下实现事务控制,极大地简化了事务处理。 实验环境主要包括 Eclipse 或 MyEclipse 开发工具,以及 Spring 4.0 及以上版本,JDK 1.7 及以上版本...

    spring事务与数据库操作

    在现代软件开发中,事务处理是非常关键的一部分,特别是在涉及多个数据操作时。Spring框架提供了强大的事务管理能力,可以方便地集成到应用程序中。Spring支持两种类型的事务管理:编程式事务管理和声明式事务管理。...

    Spring事务流程图

    总的来说,Spring事务管理是一个强大的工具,它简化了事务处理的复杂性,使得开发者能够专注于业务逻辑,而无需过多关注事务的细节。通过理解和使用Spring事务流程图,我们可以更好地设计和优化我们的应用程序,确保...

    spring声明式事务处理demo

    Spring框架的声明式事务处理是其企业级应用中的核心特性之一,它允许开发者通过配置来管理事务,而无需在代码中显式地控制事务的开始、提交和回滚。这种方式极大地提高了代码的可读性和可维护性。在这个"spring声明...

    spring-tx事务管理实例

    总的来说,Spring事务管理通过其强大的声明式事务处理能力和对各种事务策略的支持,使得开发者能够轻松地在应用程序中实现高效、一致的事务处理。通过理解并合理运用上述知识点,开发者可以构建出稳定、健壮的分布式...

    spring 事务处理

    Spring 事务处理是Java开发中一个至关重要的概念,特别是在企业级应用中,它确保了数据的一致性和完整性。Spring 提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。本篇将深入探讨Spring声明式事务...

    spring学习事务源码

    本文将深入探讨Spring事务管理的源码,理解其背后的实现机制。 首先,Spring事务管理有两种主要模式:编程式事务管理和声明式事务管理。编程式事务管理通过调用`PlatformTransactionManager`接口提供的方法进行显式...

    Spring Hibernate事务实例

    本教程将深入探讨如何在Spring框架中利用`TransactionInterceptor`进行声明式事务管理,与Hibernate集成实现高效的数据库事务控制。 首先,了解事务管理是至关重要的。事务是一组数据库操作,这些操作要么全部成功...

    spring事务操作试验

    本文将深入探讨在"spring事务操作试验"中涉及的关键知识点,并结合提供的资源进行详细阐述。 首先,Spring事务管理的核心概念是ACID(原子性、一致性、隔离性和持久性),这是所有事务系统的基础。在Spring中,事务...

    深入理解spring的事务管理机制

    Spring框架的事务管理机制是在Java开发环境中非常重要的一个组成部分,它能够帮助开发者简化事务处理的复杂度,提高应用程序的一致性和可靠性。Spring事务管理的核心是基于AOP(面向切面编程)来实现的。 **Spring...

    Spring分布式事务实现

    其中,Spring的分布式事务管理是其核心特性之一,它允许开发者在分布式系统环境中处理复杂的事务逻辑。本篇将深入探讨Spring如何实现分布式事务,以及涉及到的相关技术。 首先,分布式事务是指在多个数据库或者服务...

    spring 自定义事务管理器,编程式事务,声明式事务@Transactional使用

    本教程将深入探讨如何在Spring中实现自定义事务管理器、编程式事务处理以及声明式事务`@Transactional`的使用。 首先,让我们了解事务管理的基本概念。事务是一组数据库操作,这些操作要么全部执行,要么全部回滚,...

Global site tag (gtag.js) - Google Analytics