千家信息网

Spring注解@Transactional怎么使用

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,今天小编给大家分享一下Spring注解@Transactional怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后
千家信息网最后更新 2026年11月04日Spring注解@Transactional怎么使用

今天小编给大家分享一下Spring注解@Transactional怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

一、Transactional

声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

简而言之,@Transactional注解在代码执行出错的时候能够进行事务的回滚。

二、使用说明

  • 在启动类上添加@EnableTransactionManagement注解。

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

  • 在项目中,@Transactional(rollbackFor=Exception.class),如果类加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。

  • 在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚。

三、注解失效问题

正常情况下,只要在方法上添加@Transactional注解就完事了,但是需要注意的是,虽然使用简单,但是如果不合理地使用注解,还是会存在注解失效的问题。

@Transactional 应用在非 public 修饰的方法上

事务拦截器在目标方法执行前后进行拦截,内部会调用方法来获取Transactional 注解的事务配置信息,调用前会检查目标方法的修饰符是否为 public,不是 public则不会获取@Transactional 的属性配置信息。

@Transactional 注解属性 rollbackFor 设置错误

rollbackFor 可以指定能够触发事务回滚的异常类型。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务;其他异常不会触发回滚事务。如果在事务中抛出其他类型的异常,但却期望 Spring 能够回滚事务,就需要指定rollbackFor属性。

同一个类中方法调用,导致@Transactional失效

开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。
那为啥会出现这种情况?其实这还是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。

异常被你的 catch"吃了"导致@Transactional失效

如果你手动的catch捕获这个异常并进行处理,事务管理器会认为当前事务应该正常commit,就会导致注解失效,如果非要捕获且不失效,就必须在代码块内throw new Exception抛出异常。

数据库引擎不支持事务

开启事务的前提就是需要数据库的支持,我们一般使用的Mysql引擎时支持事务的,所以一般不会出现这种问题。

开启多线程任务时,事务管理会受到影响

因为线程不属于spring托管,故线程不能够默认使用spring的事务,也不能获取spring注入的bean在被spring声明式事务管理的方法内开启多线程,多线程内的方法不被事务控制。
如下代码,线程内调用insert方法,spring不会把insert方法加入事务就算在insert方法上加入@Transactional注解,也不起作用。

@Service  public class ServiceA {         @Transactional      public void threadMethod(){          this.insert();           System.out.println("main insert is over");          for(int a=0 ;a<3;a++){              ThreadOperation threadOperation= new ThreadOperation();              Thread innerThread = new Thread(threadOperation);              innerThread.start();          }      }         public  class ThreadOperation implements Runnable {          public ThreadOperation(){          }          @Override          public void run(){              insert();              System.out.println("thread insert is over");          }      }         public void insert(){         //do insert......         }  }

如果把上面insert方法提出到新的类中,加入事务注解,就能成功的把insert方法加入到事务管理当中

@Service  public class ServiceA {     @Autowired  private ServiceB serviceB;         @Transactional      public void threadMethod(){          this.insert();          System.out.println("main insert is over");          for(int a=0 ;a<3;a++){              ThreadOperation threadOperation= new ThreadOperation();              Thread innerThread = new Thread(threadOperation);              innerThread.start();          }      }         public  class ThreadOperation implements Runnable {          public ThreadOperation(){          }          @Override          public void run(){              serviceB.insert();              System.out.println("thread insert is over");          }      }         public void insert(){             //do insert......         }  }     @Service  public class ServiceB {         @Transactional      public void insert(){             //do insert......         }     }

另外,使用多线程事务的情况下,进行回滚,比较麻烦。thread的run方法,有个特别之处,它不会抛出异常,但异常会导致线程终止运行。

最麻烦的是,在线程中抛出的异常即使在主线程中使用try…catch也无法截获这非常糟糕,我们必须要"感知"到异常的发生。比如某个线程在处理重要的事务,当thread异常终止,我必须要收到异常的报告,才能回滚事务。这时可以使用线程的UncaughtExceptionHandler进行异常处理,UncaughtExceptionHandler名字意味着处理未捕获的异常。更明确的说,它处理未捕获的运行时异常。

如下代码
线程出要使用
①处要抛出异常
②处要捕捉异常,并且要抛出RuntimeException
③处手动处理回滚逻辑

@Service  public class ServiceA {     @Autowired  private ServiceB serviceB;         @Transactional      public void threadMethod(){          this.insert();          System.out.println("main insert is over");          for(int a=0 ;a<3;a++){              ThreadOperation threadOperation= new ThreadOperation();              Thread innerThread = new Thread(threadOperation);              innerThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {                 public void uncaughtException(Thread t, Throwable e) {                     try {                          serviceB.delete();③                     } catch (Exception e1) {                         e1.printStackTrace();                     }                 }              });              innerThread.start();          }      }         public  class ThreadOperation implements Runnable {          public ThreadOperation(){          }          @Override          public void run(){              try {                 serviceB.insert();             }catch (Exception ex){ ②              System.out.println(" Exception in run ");                 throw new RuntimeException();             }              System.out.println("thread insert is over");          }      }         public void insert(){             //do insert......         }  }     @Service  public class ServiceB {         @Transactional      public void insert() throws Exception{ ①         //do insert......         }         @Transactional      public void delete() throws Exception{              //do delete......         }     }

以上就是"Spring注解@Transactional怎么使用"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

事务 方法 注解 线程 处理 管理 事务管理 代码 属性 情况 数据 目标 知识 篇文章 类型 还是 问题 支持 运行 配置 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技名片 互联网最新的科技 浩特互联网科技 赫美联合互联网科技 四川狮子座互联网科技 佰商互联网科技有限公司 镁科技互联网资讯平台 互联网科技公司的市场部门 卫星互联网科技股票 昭通互联网科技选哪家 呼和浩特新华互联网科技学院 区块链结合互联网科技 每天都有哪些好的互联网科技 互联网企业科技类企业如何做账 从那以后互联网科技有限公司 陕西九四连强互联网科技有限公司 互联网科技品牌 数字科技和互联网金融哪个好 东风日产互联网科技公司叫什么 互联网 科技节活动 微视频大赛 互联网为科技 互联网巨头科技公司 河南住房之家互联网科技 玉溪新华互联网科技好不好 朱啸虎曾投资哪些互联网科技企业 南通创西澳互联网科技有限公司 有人说阿里系是互联网科技企业 卡尔迅互联网科技有限公司 互联网科技创业有什么好项目 颐高云石互联网科技
0