spring事物失效场景

这篇具有很好参考价值的文章主要介绍了spring事物失效场景。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在使用SpringBoot的开发过程中,我们有时候会遇到明明加了事务但是却不生效的场景,今天就稍微整理一下。

场景一:方法未被声明为事务

在Spring Boot中,事务是基于注解或XML配置的方式进行声明的。如果一个方法没有被声明为事务,那么其中的数据库操作将不会受到事务管理的影响,可能导致数据不一致的问题。

public class UserService {
    private final UserRepository userRepository;
 
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
 
    // 事务未声明
    public void updateUserStatus(Long userId, boolean active) {
        userRepository.updateStatus(userId, active);
    }
}


在上述示例中,updateUserStatus方法没有被声明为事务,即使该方法中的数据库更新操作失败,也不会回滚,可能导致数据库中的数据和应用状态不一致。

场景二:异常未被抛出

在默认情况下,Spring事务管理器只会在方法抛出RuntimeException及其子类的异常时回滚事务。如果方法抛出的是受检查异常或未抛出任何异常,事务将不会回滚。

@Service
@Transactional
public class OrderService {
    private final OrderRepository orderRepository;
 
    public OrderService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }
 
    public void placeOrder(Order order) throws IOException {
        // 数据库更新操作
        orderRepository.save(order);
 
        // 受检查异常未被抛出
        try {
            sendNotification(order);
        } catch (IOException e) {
            // 异常被捕获,事务不会回滚
        }
    }
 
    private void sendNotification(Order order) throws IOException {
        // 发送通知
        throw new IOException("Failed to send notification");
    }
}


在上述示例中,placeOrder方法中的数据库更新操作将会执行,即使在sendNotification方法中抛出了异常。因为sendNotification方法中的异常被捕获了,并未向上抛出。

场景三:方法不是公开的

在Spring事务管理中,默认情况下只会应用于公开方法。如果事务注解所标注的方法是私有、受保护或默认访问级别的,事务将无效。
 

@Service
public class UserService {
    private final UserRepository userRepository;
 
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
 
    // 私有方法,事务不会应用于该方法
    @Transactional
    private void updateUserStatus(Long userId, boolean active) {
        userRepository.updateStatus(userId, active);
    }
 
    public void activateUser(Long userId) {
        updateUserStatus(userId, true);
    }
}

 在上述示例中,updateUserStatus方法是私有的,虽然在activateUser方法中调用了它,但事务注解将不会应用于私有方法,导致事务失效。

总结

总结一些场景可能导致事务失效,例如:

  1. 未捕获的异常:如果在事务内部发生了未捕获的异常,并且该异常没有被处理或抛出到事务管理器,事务将会失效。

  2. 未使用@Transactional注解:在Spring Boot中,使用@Transactional注解来标记方法或类的事务边界。如果未使用该注解或使用错误的方式,事务将不会生效。

  3. 异步方法调用:如果在一个事务方法中调用了一个使用异步机制的方法(如使用@Async注解标记的方法),事务可能会失效,因为事务可能在异步方法执行之前就已经提交或回滚。

  4. 同一个类中的方法调用:如果在同一个类中的两个方法之间进行调用,并且这两个方法都有事务注解,事务可能会失效。这是因为Spring AOP默认是通过代理对象实现事务的,而同一个类中的方法调用不会触发代理。

代码示例:

@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Transactional
    public void createUser(User user) {
        userRepository.save(user);
        throw new RuntimeException("Oops! Something went wrong."); // 未捕获的异常导致事务失效
    }
    
    public void updateUser(User user) {
        updateUserEmail(user); // 在同一个类中的方法调用,事务可能会失效
    }
    
    @Transactional
    public void updateUserEmail(User user) {
        userRepository.save(user);
        someAsyncMethod(); // 异步方法调用,事务可能会失效
    }
    
    @Async
    public void someAsyncMethod() {
        // 异步操作
    }
}


这些是一些可能导致Spring Boot事务失效的常见场景和示例。在实际开发中,应注意事务的声明、异常的抛出和方法的可见性,以确保事务的正确应用和回滚。

为了解决这些问题,可以采取以下措施:

  1. 确保在事务方法中捕获并处理所有的异常,或者让异常传播到事务管理器。

  2. 使用正确的方式添加@Transactional注解,确保事务生效。

  3. 避免在事务方法中调用异步方法,或者通过其他方式确保异步方法执行完毕后再提交事务。

  4. 在同一个类中的方法调用时,通过从容器中获取代理对象而不是直接调用方法,以确保事务生效。文章来源地址https://www.toymoban.com/news/detail-482914.html

到了这里,关于spring事物失效场景的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring事务传播机制、实现方式、失效场景即原理

    贴一篇源码分析的好文章:https://blog.csdn.net/qq_30905661/article/details/114400417 一个事务对应一个数据库连接。 通过 this 来调用某个带有 @Transactional 注解的方法时,这个注解是失效的 spring事务底层是通过数据库事务和AOP实现的 首先对于使用@Transactional的注解的bean,spring会创建一个

    2024年02月14日
    浏览(36)
  • 揭秘Spring事务失效场景分析与解决方案

    在Spring框架中,事务管理是一个核心功能,然而有时候会遇到事务失效的情况,这可能导致数据一致性问题。本文将深入探讨一些Spring事务失效的常见场景,并提供详细的例子以及解决方案。 场景: 当一个事务方法内部调用另一个方法,而被调用的方法没有声明为 @Transact

    2024年02月02日
    浏览(43)
  • Spring事务失效场景之类内部方法调用及解决方案

    在日常开发中,经常有需要使用事务来保证数据一致性的情况。简单点的话直接在方法上面加@Transactional注解就可以了。 但这样存在一个问题,在整个业务方法层面加注解会把很多并不需要归入事务的操作也归入到了事务里面,这样会可能会出现大事务的情况,影响系统性能

    2024年01月17日
    浏览(46)
  • Spring中事务失效的8中场景 对于一个事务开子线程

    1. 数据库引擎不支持事务 这里以 MySQL为例,MyISAM引擎是不支持事务操作的,一般要支持事务都会使用InnoDB引擎,根据MySQL 的官方文档说明,从MySQL 5.5.5 开始的默认存储引擎是 InnoDB,之前默认的都是 MyISAM,所以这一点要值得注意,如果底层引擎不支持事务,那么再怎么设置也

    2024年02月16日
    浏览(39)
  • 面试官让列举Spring的事务会失效的场景,我说了8个

    本文分享自华为云社区《哪些场景下Spring的事务会失效?》,作者:冰 河 。 在日常工作中,如果对Spring的事务管理功能使用不当,则会造成Spring事务不生效的问题。而针对Spring事务不生效的问题,也是在跳槽面试中被问的比较频繁的一个问题。 今天,我们就一起梳理下有哪

    2024年02月11日
    浏览(38)
  • 【Spring】Springboot过滤器Filter和拦截器Inteceptor详解及使用场景

    Springboot过滤器Filter和拦截器Inteceptor详解及使用场景

    2024年02月13日
    浏览(42)
  • SpringBoot 自动扫描第三方包及spring.factories失效的问题

    Spring 依赖注入 就是要让spring找到要注入的类 并且识别到了 @Component、@Service 等注解。 1. 当在开发的第三方包里写明了 @Component、@Service 等等 2. 引入了包,不论第三方库的引入,还是本地jar。总之是要引入到工程的 这时候还加入不到 IOC 容器,那就说明SpringBoot工程没有扫描到

    2024年02月03日
    浏览(48)
  • mybatis事物是如何和spring事物整合的

    目录 1、mybatis事物管理器 2、SpringManagedTransactionFactory如何处理事物 3、spring事物如何设置connection连接到threadLocal 1、mybatis事物管理器 mybatis事物抽象接口类:Transaction。该接口定义了事物基本方法和获取数据库连接方法  该类有三个实现类JdbcTransaction、ManagedTransaction、SpringMan

    2024年02月15日
    浏览(37)
  • spring的事物

    这是我第三次接触事物了,mysql一次,以前的也看过一次。 事物的四大特点: 原子性: 多条sql保证同时成功,同时失败。 一致性: 在事物的开启和结束,数据库的完整性不被破坏。 隔离性: 多线程时,要保证数据的安全,也就是并发安全。 持久性: 事物处理后,对数据

    2024年02月07日
    浏览(32)
  • spring事物初始化过程分析

    1.注入4个bd 2.执行 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation 逻辑分析:遍历所有的bd: 获取beanname-判断beanname是否有长度并且没有被处理过-是否遍历放入advisedBeans- 是否是基础类-是否该跳过  4大基础类 3.执行org.springframework.aop.framework.autoprox

    2024年02月02日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包