张晨的个人博客

Spring注解@Transactional管理事务

张晨的个人博客2014-07-18Java技术 2560 0A+A-

 

@Transactional 事务回滚

 

Spring的AOP事务管理默认是针对unchecked exception回滚(运行期异常,Runtime Exception)。

unchecked ,就是不用手工写try catch的exception

 

Exception作为基类,下面还分checked exception和unchecked exception。如果客户端可以通过其他的方法恢复异常,那么这种异常就是checked exception;如果客户端对出现的这种异常无能为力,那么这种异常就是Unchecked exception;简单来说,继承于RuntimeException的都是unchecked exception。

 

Error:
1.总是不可控制的(unchecked) 
2.经常用来用于表示系统错误或低层资源的错误 
3.如何可能的话,应该在系统级被捕捉 

Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked) 
2.表示一个由程序员导致的错误 
3.应该在应用程序级被处理

 

Java 中定义了两类异常: 
1) Checked exception: 这类异常都是Exception的子类 。异常的向上抛出机制进行处理,假如子类可能产生A异常,那么在父类中也必须throws A异常。可能导致的问题:代码效率低,耦合度过高。
2) Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是非凡的,它们 不能通过client code来试图解决,所以称为Unchecked exception 。

 

在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。

Spring默认情况下会对运行期例外(RunTimeException)进行事务回滚。这个例外是unchecked

如果遇到checked意外就不回滚。

如何改变默认规则:

1 让checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)

2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED)

4 如果配置了多个事务,可以设置为@Transactional(value="myTransaction",rollbackFor=Exception.class)

 

注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须在catch中再往外抛t:ry{}catch{new throw RuntimeException}。

 

@Transactional设置:

propagation:事务传播性设置,Propagation枚举类型。Spring支持的事务传播属性包括7种:

    PROPAGATION_MANDATORY:方法必须在事务中执行,否则抛出异常。

    PROPAGATION_NESTED:使方法运行在嵌套事务中,否则和PROPAGATION_REQUIRED一样。

    PROPAGATION_NEVER :当前方法永远不在事务中运行,否则抛出异常。

    PROPAGATION_NOT_SUPPORTED:定义为当前事务不支持的方法,在该方法执行期间正在运行的事务会被暂停

    PROPAGATION_REQUIRED:当前的方法必须运行在事务中,如果没有事务就新建一个事务。新事务和方法一起开始,随着方法返回或者抛出异常时终止。

    PROPAGATION_REQUIRED_NEW :当前方法必须新建一个事务,如果当前的事务正在运行则暂停。

    PROPAGATION_SUPPORTS :规定当前方法支持当前事务,但是如果没有事务在运行就使用非事务方法执行。

isolation:事务隔离性级别设置,Isolation枚举类型

    ISOLATION_DEFAULT :使用数据库默认的隔离级别

    ISOLATION_COMMITTED:允许其他事务已经提交的更新(防止脏读取)

    ISOLATION_READ_UNCOMMITTED:允许读取其他事务未提交的更新,会导致三个缺陷发生。执行速度最快

    ISOLATION_REPEATABLE_READ :除非事务自身更改了数据,否则事务多次读取的数据相同(防止脏数据,多次重复读取)

    ISOLATION_SERIALIZABLE:隔离级别最高,可以防止三个缺陷,但是速度最慢,影响性能。

 

readOnly:读写性事务,只读性事务,布尔型

    对数据库的操作中,查询是使用最频繁的操作,每次执行查询时都要从数据库中重新读取数据,有时多次读取的数据都是相同的,这样的数据操作不仅浪费了系统资源,还影响了系统速度。对访问量大的程序来说,节省这部分资源可以大大提    升系统速度。

   将事务声明为只读的,那么数据库可以根据事务的特性优化事务的读取操作

timeout:超时时间,单位秒

事务可能因为某种原因很长时间没有反应,这期间可能锁定了数据库表,影响性能。设置超时时间,如果超过该时间,事务自动回滚。

rollbackFor:一组异常类的实例,遇到时必须进行回滚

rollbackForClassname:一组异常类的名字,遇到时必须进行回滚

noRollbackFor:一组异常类的实例,遇到时必须不回滚

noRollbackForClassname:一组异常类的名字,遇到时必须不回滚

 

以上内容转至网络,少部分进行了修改

———————————————————

 

在实际应用过程中,可以在项目中添加自定义异常类BusinessException,继承RuntimeException,需要回滚时抛出此异常即可(再次提醒不要try catch此异常不然事务回滚不会生效在上层捕捉处理就可以了)

 


public class BusinessException extends RuntimeException {

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 8204576467629716583L;

	public BusinessException(String msg) {
		super(msg);
	}

}



 

文章关键词
Spring
注解
Transactional
事务回滚
发表评论