Springboot中@Transactional注解与异常处理机制方式

 更新时间:2024年08月06日 11:07:56   作者:HelloBlues  
这篇文章主要介绍了Springboot中@Transactional注解与异常处理机制方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Springboot @Transactional注解与异常处理机制

@Transactional注解的方法默认会捕获所有非检查异常,即RuntimeException和Error,可以通过括号声明显示指定处理异常类,如Exception.class

关于异常处理机制:

当代码抛出异常时,异常处理的优先级如下:

  • try-catch 块:如果在代码中使用了 try-catch 块来捕获异常,异常将会首先被 try-catch 块捕获并处理。只有在 try-catch 块中未处理(重新抛出)异常时,异常才会继续传播。
  • @Transactional:如果异常从 try-catch 块中传播出来,Spring 的事务管理器(由 @Transactional 注解管理)会捕获异常并决定是否回滚事务。事务处理之后,异常继续传播。
  • @ExceptionHandler:最后,异常会被全局异常处理器(由 @ControllerAdvice 和 @ExceptionHandler 注解管理)捕获并处理。

因此,对于手动捕获的异常,需要手动将其抛出才会被@Transactional处理器捕获,全局处理器的优先级最后,除了特殊的异常可能需要调整传播顺序,大部分不需要考虑其影响。

@Transactional错误集锦以及如何正确使用

原理

@Transactional 是声明式事务管理 编程中使用的注解,通过Spring AOP在注解修饰方法的前后织入事务管理的实现语句,所以开发者只需要通过一个注解就能代替一系列繁琐的事务开始、事务关闭等重复性的编码任务。

添加位置

  • 接口实现类或接口实现方法上,而不是接口类中。
  • 访问权限:public 的方法才起作用。@Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。
  • 系统设计:将标签放置在需要进行事务管理的方法上,而不是放在所有接口实现类上:只读的接口就不需要事务管理,由于配置了@Transactional就需要AOP拦截及事务的处理,可能影响系统性能。

错误案例

1.同一个类中调用

public class A {
    
    public void methodA() {
        methodB();
        
        // 其他操作
    }

    @Transactional
    public void methodB() {
        // 写数据库操作
    }
    
}

上面案例是错误的基于Spring Aop的拦截机制,将会忽略事务。

解决方式如下:

@Service@AllArgsConstructorpublic class A {        private B b;        public void methodA() {        b.methodB();        // 其他操作    }}@Servicepublic class B {
    @Transactional    public void methodB() {        // 写数据库操作    }    }

注意:这里的B类没有用@Autowrire,构造函数用Lombok的@AllArgsConstructor生成 自动注入了。

2. @Transactional修饰方法不是public

public class TransactionalMistake {
    
    @Transactional
    private void method() {
        // 写数据库操作
    }
    
}

这也是基于Spring AOP实现的注解所要满足的要求。这个最简单, 直接把方法访问类型改成public即可。

3. 不同的数据源

public class TransactionalMistake {

    @Transactional
    public void createOrder(Order order) {
        orderRepo1.save(order);
        orderRepo2.save(order);
    }

}

上面这个例子里的orderRepo1和orderRepo2是连接的两个不同数据源。

默认情况下,这种跨数据源的事务是不会成功的。

如果要在多个数据源之间实现事务,那么可以引入JTA。

4. 回滚异常配置不正确

默认情况下,仅对RuntimeException和Error进行回滚。

如果不是的它们及它们的子孙异常的话,就不会回滚。

如果不是RuntimeException,但也希望触发回滚,那么可以使用rollbackFor属性来指定要回滚的异常。

public class TransactionalMistake {

    @Transactional(rollbackFor = XXXException.class)
    public void method() throws XXXException {

    }

}

5. 数据库引擎不支持事务

spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

这里的spring.jpa.database-platform配置主要用来设置hibernate使用的方言。

这里特地采用了MySQL5InnoDBDialect,主要为了保障在使用Spring Data JPA时候,Hibernate自动创建表的时候使用InnoDB存储引擎,不然就会以默认存储引擎MyISAM来建表,而MyISAM存储引擎是没有事务的。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring WebFlux 与 WebClient 使用指南及最佳实践

    Spring WebFlux 与 WebClient 使用指南及最佳实践

    WebClient是Spring WebFlux模块提供的非阻塞、响应式HTTP客户端,基于Project Reactor实现,适用于高并发场景spring webclient,本文给大家介绍Spring WebFlux与WebClient使用指南及最佳实践,感兴趣的朋友一起看看吧
    2025-07-07
  • 如何利用JAVA实现走迷宫程序

    如何利用JAVA实现走迷宫程序

    最近经常在机房看同学在玩一个走迷宫的游戏,比较有趣,自己也用java实现了一个,这篇文章主要给大家介绍了关于如何利用JAVA实现走迷宫程序的相关资料,需要的朋友可以参考下
    2021-06-06
  • java生成指定范围随机数的多种代码

    java生成指定范围随机数的多种代码

    今天在写代码的时候需要用到一个生成指定范围随机数的函数,百度了一下,发现了很多种方法,这里简单为大家整理一下,方便需要的朋友
    2017-08-08
  • 浅析Java中的访问控制权限

    浅析Java中的访问控制权限

    这篇文章主要介绍了浅析Java中的访问控制权限,在Java中,提供了四种访问权限控制,分别是默认访问权限、public、private以及protected,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • RocketMQ事务消息机制详解

    RocketMQ事务消息机制详解

    这篇文章主要介绍了RocketMQ事务消息机制详解,RocketMQ服务端将消息持久化之后,向发送方返回Ack确认消息已经发送成功,由于消息为半事务消息,在未收到生产者对该消息的二次确认前,此消息被标记成"暂不能投递"状态,需要的朋友可以参考下
    2024-01-01
  • Java调用Coze API详细实现步骤

    Java调用Coze API详细实现步骤

    Coze是一款由字节跳动推出的低代码AI开发平台,让非专业开发者也能轻松创建智能应用,这篇文章主要介绍了Java调用Coze API的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-01-01
  • java异步导出的实现过程

    java异步导出的实现过程

    这篇文章主要介绍了java异步导出的实现过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-10-10
  • java实现图形化界面计算器

    java实现图形化界面计算器

    这篇文章主要为大家详细介绍了java实现图形化界面计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • Spring Boot实现文件上传下载

    Spring Boot实现文件上传下载

    这篇文章主要为大家详细介绍了Spring Boot实现文件上传下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • mybatis实现查询操作及获得添加的ID

    mybatis实现查询操作及获得添加的ID

    这篇文章主要介绍了mybatis实现查询操作及获得添加的ID,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11

最新评论