关于Spring中@Transactional事务回滚的注意事项_第1页
关于Spring中@Transactional事务回滚的注意事项_第2页
关于Spring中@Transactional事务回滚的注意事项_第3页
关于Spring中@Transactional事务回滚的注意事项_第4页
关于Spring中@Transactional事务回滚的注意事项_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第关于Spring中@Transactional事务回滚的注意事项目录一、Spring默认事务1.1、抛出unchecked和checked异常都回滚1.2、总结二、使用Spring中@Transactional注解的注意事项

一、Spring默认事务

Spring中@Transactional注解,默认情况下,只对抛出的RuntimeException异常,才会事务回滚。

如果事务的方法中抛出unchecked异常(RuntimeException),事务会进行回滚(rollback);如果事务的方法中抛出是checked异常(Exception),事务不会回滚。

也就是说,默认情况下,@Transactional注解只对抛出的RuntimeException异常和其子类异常才有效,对Exception及Exception的子类异常无效。

伪代码说明

//@Transactional默认就是RuntimeException有效,抛出RuntimeException时,事务会回滚。

@Transactional

publicvoidmethodName1(){

//...各种的业务逻辑省略

thrownewRuntimeException("RuntimeException");

//@Transactional默认就是RuntimeException有效,抛出Exception时,事务不会回滚。

@Transactional

publicvoidmethodName22(){

//...各种的业务逻辑省略

thrownewException("Exception");

//@Transactional指定回滚事务是Exception时,遇到RuntimeException时,事务不会回滚

@Transactional(rollbackFor=Exception.class)

publicvoidmethodName3(){

//...各种的业务逻辑省略

thrownewRuntimeException("RuntimeException");

//@Transactional指定回滚事务是Exception时,遇到异常Exception时,事务会回滚,

@Transactional(rollbackFor=Exception.class)

publicvoidmethodName4(){

//...各种的业务逻辑省略

thrownewException("Exception");

}

@Transactional相当于@Transactional(rollbackFor=RuntimeException.class),只对抛出的RuntimeException异常,才会事务回滚。

1.1、抛出unchecked和checked异常都回滚

如果希望无论抛出是RuntimeException(unchecked),还是Exception(checked),事务都要回滚。

@Transactional(rollbackFor={RuntimeException.class,Exception.class})

publicvoidmethodName5(){

//...业务省略

if(){

thrownewRuntimeException("RuntimeException");

//...业务省略

if(){

thrownewException("Exception");

}

1.2、总结

Spring中@Transactional,默认只对抛出的RuntimeException的出常,事务才会回滚。如果希望无论抛出是RuntimeException,还是Exception,事务都要回滚,请使用如下配置。

@Transactional(rollbackFor={RuntimeException.class,Exception.class})

二、使用Spring中@Transactional注解的注意事项

@Transactional注解只能应用到public的方法上。如果你在protected、private或者package-visible的方法上使用@Transactional注解,它也不会报错,但是这个被注解的方法将不会展示已配置的事务设置。配置proxy-target-class是指定基于接口的,还是基于类的代理被创建。如果proxy-target-class=false(默认值),那么标准的JDK基于接口的代理。如果proxy-target-class=true,那么基于类的代理将起作用(需要CGLIB库)。@Transactional注解加在具体方法(或类)上面,而不是接口上面。在接口上使用@Transactional注解,只能当你设置了基于接口的代理时它才生效。因为注解是不能继承的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。@Transactional的事务是通过基于接口的,或者是基于类的代理才能被创建。在同一个类中一个方法调用另一个有事务注解的方法,事务是不会起作用的。

这条能理解吗?下面是解释说明。

伪代码说明

@Serive

publicclassXxxService{

publicvoidaa(){

//业务...

bb()

//业务...

@Transactional

publicvoidbb(){

//业务...

@Controller

publicclassXxxController(){

@Autowired

XxxServicexxxService;

@RquestMapping("/hello")

publicvoidhello(){

xxxService.aa();

XxxController.hello()调用XxxService时,没有开启事务,在aa()、bb()发生的RuntimerException不会事务回滚。

分析说明:

(1)因为aa()没有@Transactional注解,因此XxxController调用XxxService时,没有开启事务;

(2)aa()中调有bb()只是方法的调用(代码片段的调用)。类似于Thread中,开启线程是通过start()方法,而不是直接调用run()方法。

spring在扫描bean的时候会扫描方法上是否包含@Transactional事务注解,如果包含,则spring会为这个bean动态地生成一个子类(即代理类,proxy),代理类是继承原来那个bean。

当这个有事务注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用之前就会开启事务(transaction)。

但是,如果先调用一个没有事务

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论