酷站(www.ku0.com)-致力于为互联网从业者提供动力!

热门关键词:  企业  as  baidu  c4rp3nt3r  美女
阿里云爆款特惠,精选爆款产品低至0.55折

springBoot service层事务控制的操作教程

来源:转载 作者:秩名 人气: 发布时间:2021-02-23
本篇文章主要介绍了springBoot service层事务控制的操作教程,对大家的学习或者工作具有一定的参考学习价值,感兴趣的小伙伴们可以参考一下,也感谢大家对酷站(ku0.com)的支持。

springBoot使用事物比较简单,在Application启动类s上添加@EnableTransactionManagement注解,然后在service层的方法上添加@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注解进行修饰。

注解在方法上:

@Autowired
private MyBatisDao dao;
@Transactional
@Override
public void insert(Test test) {
 dao.insert(test);
 throw new RuntimeException("test");//抛出unchecked异常,触发事物,回滚 
}
 
@Transactional(noRollbackFor=RuntimeException.class)
@Override
public void insert(Test test) {
 dao.insert(test);
 //抛出unchecked异常,触发事物,noRollbackFor=RuntimeException.class,不回滚 
 throw new RuntimeException("test");
}
 
@Transactional(propagation=Propagation.NOT_SUPPORTED)
@Override
public void insert(Test test) {
 //事物传播行为是PROPAGATION_NOT_SUPPORTED,以非事务方式运行,不会存入数据库 
 dao.insert(test);
}
 

注解在类上:当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性

@Transactional
public class MyBatisServiceImpl implements MyBatisService { 
 @Autowired
 private MyBatisDao dao;
   
 @Override
 public void insert(Test test) {
  dao.insert(test);
  //抛出unchecked异常,触发事物,回滚
  throw new RuntimeException("test");
 }
 

注意:有时候在开发时往往出现了添加注解后却无法回滚

原因:默认spring事务只在发生未被捕获的 RuntimeException 时才回滚。

spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚

换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚。

解决方案:

1.在service层方法抛出RuntimeException异常(如在Catch中需要抛出自定义的异常则只需自定义异常继承RuntimeException即可),并继续捕获和处理这个异常。

2.在service层方法的catch语句中增加:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

语句,手动回滚,这样上层就无需去处理异常。

补充:springboot多个service互相调用的事务处理

今天,想在一个service的方法A中,调用另一个service的方法B,方法A和方法B均存在数据库插入操作,并且@Transaction注解也都加了,但是当B方法中抛出异常时,A中的插入语句还是能够执行成功。

注解配置如下:

 
@Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED)

百思不得其解,再查找了相关资料后,问题还是出在@Transaction注解的配置上,需要配置异常回滚。

@Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)

这样,当B方法中抛出异常时,A中的操作也会进行回滚,事务就会起到控制作用。

版权声明:本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 959677720#qq.cn(#换@) 举报,一经查实,本站将立刻删除。
原文链接:https://www.cnblogs.com/tongxuping/p/7650293.html

相关文章

  • springBoot service层事务控制的操作教程

    springBoot service层事务控制的操作教程

    springBoot使用事物比较简单,在Application启动类s上添加@EnableTransactionManagement注解,然后在service层的方法上添加@Transactional注解 @Transactional属性 属性 类型 描述 value String 可选的限定描述符,指定使用的事务管理器 ......
    02-23
  • 解决idea中@Data标签getset不起作用的问题

    解决idea中@Data标签getset不起作用的问题

    spring cloud中使用@Data标签,不用手动添加get set方法,但是如果项目中其他类中使用getset方法,如果报错,原因是idea中没有添加Lombok插件,添加上插件便可以解决。 截图如下 补充:Intellij IDEA无法使用lombok、@Data不起作用,set......
    02-23
  • Java中Singleton的3种实现方式

    Java中Singleton的3种实现方式

    一、什么是Singleton? 《设计模式》的作者、Eclipse和 Junit 的开发者 Erich Gamma 在它的理论体系中将 Singleton 定义为仅仅被实例化一次的类。在当今面向对象程序的实际开发中,Singleton 通常被用来代表一个无状态的对象,例如函数和......
    02-21
  • Java动态加载类详解

    Java动态加载类详解

    在讲解动态加载类之前呢,我们先弄清楚为什么要动态加载类,静态加载不行吗?我们可以看下面的实例: 我在文件夹里写了Office.java 类和 Word.java类,如下: Office.java class Office{ public static void main(String[] args){ if(arg......
    02-21
  • 解决redisTemplate中leftPushAll隐性bug的问题

    解决redisTemplate中leftPushAll隐性bug的问题

    前言 请看下面代码: String key = String.format(test_key:%s, System.currentTimeMillis()/1000); String key2=key+_2; String key3=key+_3; ListString t1=new ArrayList(); t1.add(2); t1.add(3); t1.add(4); t1.add(5); t1.add(1); ......
    02-17
  • 解决Intellij IDEA覆盖tomcat配置的问题

    解决Intellij IDEA覆盖tomcat配置的问题

    刚刚遇到bug,每次修改自己环境里tomcat的server.xml,再次在Intellij里启动tomcat之后,修改就消失了,心态很炸裂hhh 研究了好久,最终把目光放在了下图所示的地方。 一开始以为是自己环境变量没配,但是看了一下发现没问题,又在cmd里......
    02-12
  • Java使用FTP上传文件并模拟接受的教程

    Java使用FTP上传文件并模拟接受的教程

    0. 导入相关依赖 !-- FTP --dependency groupIdcommons-net/groupId artifactIdcommons-net/artifactId version3.6/version /dependency !-- Hutool:一个小而全的Java工具类库,具体介绍参照附录1 -- dependency groupIdcn.hutool/groupI......
    02-12
  • spring security认证异常后返回中文提示的问题详解

    spring security认证异常后返回中文提示的问题详解

    1.加载中文提示类 @Configurationpublic class ReloadMessageConfig { /** * 加载中文的认证提示信息 * * @return */ @Bean public ReloadableResourceBundleMessageSource messageSource() { ReloadableResourceBundleMessageSource mes......
    02-04
  • java中i = i++和i =++i的深入详解

    java中i = i++和i =++i的深入详解

    public class Count { public static void main(String[] args) { int i = 0; i = i++ ; System.out.println(i); }} 上面代码输出的i为0,如果是把i = i++换成i=++i,又会输出1,这是由于i++是先赋值,再计算导致,但是为什么先赋值呢? ......
    02-01
  • springboot使用CommandLineRunner解决项目启动时初始化资源

    springboot使用CommandLineRunner解决项目启动时初始化资源

    前言: 在我们实际工作中,总会遇到这样需求,在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等。 今天就给大家介绍一个 Spring Boot 神器,专门帮助大家解决项目启动初始化资源操作。 这个神器就是Comm......
    02-01

最新更新