首页 > 其他分享 >事务 - 失效的场景

事务 - 失效的场景

时间:2024-10-20 21:42:59浏览次数:1  
标签:回滚 场景 Spring Transactional 事务 void 失效 public

1. 没有使用代理

场景: 如果你在一个类内部调用同一个类中的另一个方法,Spring 事务管理无法生效。

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 当在 controller 调用 executeTask 时事务会失效
 * 1,因为标注了 @Transaction 注解,spring 会为 MyService 创建一个代理对象
 * 2,controller 调用 executeTask 方法时,调用的是真实对象的方法,因为这个方法没有标注事务注解
 * 3,executeTask 再调用 performTask 时,其实是 this.performTask,这里的 this 是普通对象,而不是代理对象
 */
@Service
public class MyService {

    @Transactional
    public void performTask() {
        // 模拟数据库操作
        System.out.println("Performing task...");
        // 这里可以添加更多数据库操作代码
        // 例如:userRepository.save(new User());
    }

    public void executeTask() {
        performTask();  // 直接调用同一类中的方法
    }
}

原因: 这是因为 Spring 事务管理是基于代理的。当你在一个类中调用另一个方法时,实际上是在同一个对象的上下文中执行的,这样事务注解不会被代理拦截,导致事务失效。

解决方法: 1,将方法提取到不同的类中,2,在同一个类中使用 self 注入。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Autowired
    private MyService self;  // 自我注入

    @Transactional
    public void performTask() {
        System.out.println("Performing task...");
        // 数据库操作
    }

    public void executeTask() {
        self.performTask();  // 使用自我注入调用,因为此时 self 已经是代理对象了,所以会走 AOP 的通知
    }
}

2. 非运行时异常

场景: Spring 默认只对运行时异常(RuntimeException)进行回滚,如果抛出的是检查性异常(如 IOException),则不会回滚事务。

@Transactional
public void test(){
	userDao.save(user);
   	new File("D:\\不存在的文件.jpg")
}

原因: 这是 Spring 事务管理的默认行为,非运行时异常不会触发事务回滚。

解决方法: 可以在 @Transactional 注解中指定回滚的异常类型,例如:

@Transactional(rollbackFor = Exception.class)
public void test(){
	userDao.save(user);
   	new File("D:\\不存在的文件.jpg")
}

3. 事务传播行为设置不当

场景: 在多个事务之间的交互时,传播行为设置不当可能导致事务失效。

// 订单 service
@Service
public class OrderService {
    
    private final PaymentService paymentService;

    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    @Transactional
    public void createOrder() {
        // 订单创建逻辑
        System.out.println("Creating order...");
        
        // 调用 PaymentService 处理支付
        paymentService.processPayment();
        
        // 其他订单处理逻辑
    }
}

// 支付 service
@Service
public class PaymentService {

    // 这个方法使用的是 REQUIRES_NEW,会新开一个事务,出现异常只是当前事务会回滚,不会影响上层的事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void processPayment() {
        // 支付处理逻辑
        System.out.println("Processing payment...");
        // 模拟异常
        if (true) {
            throw new RuntimeException("Payment failed!");
        }
    }
}

4. 隔离级别不合适

场景: 在高并发情况下,使用不合适的隔离级别可能导致事务表现不符合预期。

# 1,假设隔离级别是读未提交
# 2,A 事务先新增一条数据
# 3,此时 B 事务读到这条数据了,做业务的途中发生异常,要回滚数据(将要回滚还没有回滚的时候,A RollBack 了)
# 4,B 事务咋回滚,要回滚的数据都没了

5. Spring Boot 和 Spring 版本不兼容

场景: 在使用 Spring Boot 的时候,某些 Spring 版本之间可能存在兼容性问题。

原因: 在不同版本的 Spring 或 Spring Boot 中,事务管理的实现可能会有所不同。

解决方法: 确保使用兼容的 Spring 和 Spring Boot 版本,并查阅相应的文档。

标签:回滚,场景,Spring,Transactional,事务,void,失效,public
From: https://www.cnblogs.com/cyrushuang/p/18487998

相关文章

  • 网关失效前端请求一直报404
    这个问题是网关什么的我都配置的对但是前端页面请求过来就直接报404问题原因全局过滤器的使用全局过滤器是作用于所有路由的过滤器,无需单独配置。在SpringCloudGateway中,全局过滤器可以用来实现一些统一化处理的业务需求,例如权限认证、IP访问限制等。然而,如果不正确使用全局......
  • 事务 - 编程式事务
    packagecom.example.demo.service;importcom.example.demo.mapper.UserMapper;importcom.example.demo.model.User;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.tran......
  • Spring Boot 整合 RocketMQ 之事务消息
    前言:上一篇我们分享了RocketMQ完成顺序消息发送的案例,本篇我们来分享一下RocketMQ事务消息的使用。RocketMQ系列文章传送门RocketMQ的介绍及核心概念讲解SpringBoot整合RocketMQ之普通消息SpringBoot整合RocketMQ之定时/延时消息SpringBoot整合Rocke......
  • 事务
    事务的基本概念事务是由一系列操作组成的逻辑单元,这些操作要么全部成功,要么全部失败,一个事务具有以下特性(ACID):原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成。一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。隔离性(Isolat......
  • 场景化运营与定制开发链动 2+1 模式 S2B2C 商城小程序的融合
    摘要:本文深入探讨了场景化运营的重要性以及其在商业领域的广泛应用。通过分析电梯广告、视频网站和电商产品的场景化运营方式,引入关键词“定制开发链动2+1模式S2B2C商城小程序”,阐述了如何将场景化运营理念融入到该小程序的开发与推广中,以提升用户体验和商业价值。一、引......
  • USB协议详解第17讲(USB事务总结)
    1.USB传输回顾前面讲了四种传输的类型的事务组成,包括控制传输,同步传输,批量传输,中断传输。2.USB事务总结本节我们来对事务(transaction)相关内容做以总结,从前面学习中我们可以看到其实事务有三种类型,Setup事务、DataIN事务、DataOUT事务。Setup事务:主要向设备发送控制命令;Dat......
  • USB协议详解第15讲(USB传输-批量传输及事务组成)
    1.前言前面讲过USB一个传输由多个事务组成,一个事务由多个包实体组成。传输又分为控制传输、同步传输、批量传输、中断传输四种,上一节我们讲了同步传输细节及事务组成,今天我们主要讲解批量传输及事务组成,批量传输也叫大容量传输。批量传输和同步传输类似,是使用批量事务(BulkTrans......
  • USB协议详解第16讲(USB传输-中断传输及事务组成)
    1.前言中断传输用于那些频率不高,但是对周期有一定要求的数据传输。具有保证的带宽,并能在下一个周期对先前错误的传输进行重传。中断端点在端点描述符中要报告主机对此端点的查询时间,主机会保证在小于这个时间间隔的范围内安排一次传输,比如HOST主机1ms内向鼠标设备请求一次数据。......
  • 常见的性能效率失效模式及原因
    目录一、在所有负载水平下响应缓慢二、中高负载下反应缓慢三、随着时间的推移,响应降低四、高负载或超高负载下出错处理不充分或粗暴五、高延迟六、低吞吐量七、资源耗尽八、负载下的稳定性差九、扩展性问题在动态测试过程中可以发现许多不同的性能效率失效模式,以下......
  • 几首会让我回到某些场景的歌曲
    1.《热爱105℃的你》由阿肆作词、作曲并演唱的歌曲,于2019年7月4日以单曲的形式发布歌词:SuperIdol的笑容都没你的甜八月正午的阳光都没你耀眼热爱105℃的你滴滴清纯的蒸馏水你不知道你有多可爱跌倒后会傻笑着再站起来......回忆:这首歌带我回到了2021年7月暑假的杭州......