spring事务

原创 2016年08月31日 09:55:11

spring支持编程式事务管理和声明式事务管理两种方式。

        编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

        声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

       显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持。和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如,可以将需要进行事务管理的代码块独立为方法等等。

         声明式事务管理也有两种常用的方式,一种是基于tx和aop名字空间的xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。

spring事务特性

spring所有的事务管理策略类都继承自org.springframework.transaction.PlatformTransactionManager接口

 

spring事务回滚规则

     指示spring事务管理器回滚一个事务的推荐方法是在当前事务的上下文内抛出异常。spring事务管理器会捕捉任何未处理的异常,然后依据规则决定是否回滚抛出异常的事务。

        默认配置下,spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务。还可以编程性的通过setRollbackOnly()方法来指示一个事务必须回滚,在调用完setRollbackOnly()后你所能执行的唯一操作就是回滚。


一、基于注解的声明式事务管理配置@Transactional

        <!-- 配置 Spirng 的 JdbcTemplate -->
	<bean id="jdbcTemplate"  class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	
	<!-- 配置事务管理器 -->
	<bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 启用事务注解 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>


@Transactional注解

 

@Transactional属性 

 

属性 类型 描述
value String 可选的限定描述符,指定使用的事务管理器
propagation enum: Propagation 可选的事务传播行为设置
isolation enum: Isolation 可选的事务隔离级别设置
readOnly boolean 读写或只读事务,默认读写
timeout int (in seconds granularity) 事务超时时间设置
rollbackFor Class对象数组,必须继承自Throwable 导致事务回滚的异常类数组
rollbackForClassName 类名数组,必须继承自Throwable 导致事务回滚的异常类名字数组
noRollbackFor Class对象数组,必须继承自Throwable 不会导致事务回滚的异常类数组
noRollbackForClassName 类名数组,必须继承自Throwable 不会导致事务回滚的异常类名字数组

 

 

 

用法

       @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

         虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional  注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

        默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

 

//	@Transactional(propagation=Propagation.REQUIRES_NEW,
//			isolation=Isolation.READ_COMMITTED,
//			noRollbackFor={UserAccountException.class})
	@Transactional(propagation=Propagation.REQUIRES_NEW,
			isolation=Isolation.READ_COMMITTED,
			readOnly=false,
			timeout=3)
	@Override
	public void purchase(String username, String isbn) {
				
		//1. 获取书的单价
		int price = bookShopDao.findBookPriceByIsbn(isbn);
		
		//2. 更新数的库存
		bookShopDao.updateBookStock(isbn);
		
		//3. 更新用户余额
		bookShopDao.updateUserAccount(username, price);
	}


 

 

  二、基于注解的声明式事务管理配置,xml配置

只看xml就可以了

<!-- 2. 配置事务属性 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 根据方法名指定事务的属性 -->
			<tx:method name="purchase" propagation="REQUIRES_NEW"/>
			<tx:method name="get*" read-only="true"/>
			<tx:method name="find*" read-only="true"/>
			<tx:method name="*"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.atguigu.spring.tx.xml.service.*.*(..))" 
			id="txPointCut"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>	
	</aop:config>


 

 

 

 

 

MySQL与Spring事务管理

数据库事务是保证在并发情况下能够正确执行的重要支撑,MySQL常见的数据库引擎中支持事务的是InnoDB,事务就是一系列操作,正确执行并提交,如果中途出现错误就回滚。事务要保证能够正常的执行,就必须要...
  • micro_hz
  • micro_hz
  • 2017年03月02日 20:08
  • 687

spring是如何管理 事务的

Spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活方便。    1、传统使用JDBC的事务管理  ...
  • u013700340
  • u013700340
  • 2014年12月23日 23:04
  • 4840

关于Spring嵌套事务

不久前,为了避免事务的嵌套,刻意去修改以前的设计,导致各部分之间经常出现职责的混淆和重复,颇为头痛.今天在一篇名为《解惑 spring 嵌套事务》文章中找到了答案.原因出在没有能够深刻理解事务声明中不...
  • liufei198613
  • liufei198613
  • 2016年05月26日 15:04
  • 628

浅析Spring 事务(二十一) spring事务的传播行为

经过我们上面一个章节的初步了解,我们已经知道了Spring事务的基本配置,今天我们一起接着讨论一下spring事务的传播...
  • linuu
  • linuu
  • 2016年03月29日 16:07
  • 1989

Spring事务管理(一)什么是事务?

事务的概念 并发事务导致的问题 我们在实际业务场景中,经常会遇到数据频繁修改读取的问题。在同一时刻,不同的业务逻辑对同一个表数据进行修改,这种冲突很可能造成数据不可挽回的错乱,所以我...
  • gloomy_114
  • gloomy_114
  • 2017年03月15日 14:07
  • 3853

揭开Spring事务处理

Spring事务处理你未关注过的原理 本文对Spring实现事务处理的真正原理进行追究,从而从中提炼出一些见解。其中讲解内容可能会存在一定的误导,还希望指出,内容仅供参考!(经过本人后期继续研...
  • zhousenshan
  • zhousenshan
  • 2016年06月03日 17:04
  • 567

spring事物配置,声明式事务管理和基于@Transactional注解的使用

事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。 spring支持编程式事务管理和声明式事务管理两种方式。 编程式事务管理使用TransactionTempla...
  • bao19901210
  • bao19901210
  • 2014年12月04日 15:17
  • 131789

Spring 事务的配置和使用详解(包括手动对事务的控制部分)

最近项目中用到了spring的注解类的事务管理,所以特地学习和记录一下spring的配置和使用。项目中使用的是springMVC + mybatis + mysql。spring的版本是4.3.0.R...
  • whbing1471
  • whbing1471
  • 2017年01月05日 20:14
  • 4172

Spring事务配置的五种方式 巨全!不看后悔,一看必懂!

前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识。通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的。...
  • hjm4702192
  • hjm4702192
  • 2013年12月12日 09:56
  • 23322

[spring]事务传播级别隔离级别以及高并发下的应用经验

事务是逻辑处理原子性的保证手段,通过使用事务控制,可以极大的避免出现逻辑处理失败导致的脏数据等问题。 事务最重要的两个特性,是事务的传播级别和数据隔离级别。传播级别定义的是事务的控制范围,事务隔离级...
  • f8152
  • f8152
  • 2016年11月14日 22:19
  • 676
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:spring事务
举报原因:
原因补充:

(最多只允许输入30个字)