首页 > 其他分享 >Spring中导致事务传播失效的情况(自调用、方法访问权限、异常处理不当、传播类型选择错误等。在实际开发中,务必确保事务方法正确配置)

Spring中导致事务传播失效的情况(自调用、方法访问权限、异常处理不当、传播类型选择错误等。在实际开发中,务必确保事务方法正确配置)

时间:2024-10-23 13:20:53浏览次数:3  
标签:解决办法 事务 调用 Spring 传播 transactionalMethod public

文章目录

在 Spring 中,事务传播机制可以有效管理事务的传播和行为。但在某些情况下,事务传播可能会失效,导致事务没有按预期进行传播和处理。以下是常见导致事务传播失效的几种情况:

1. 自调用(内部调用)导致事务失效

这是最常见的问题之一。当一个类的非事务方法内部调用自身的事务方法时,Spring 的事务代理无法起作用。这是因为 Spring 的事务管理是基于 AOP 实现的,它通过动态代理在方法执行前后插入事务逻辑。但如果是同一个类的内部调用,Spring 无法通过代理拦截这个调用,事务不会被启动。

示例:

public class MyService {

    @Transactional
    public void transactionalMethod() {
        // 事务逻辑
    }

    public void nonTransactionalMethod() {
        // 通过内部调用执行事务方法
        transactionalMethod();
    }
}

在上述代码中,如果在 nonTransactionalMethod() 中调用了 transactionalMethod()transactionalMethod() 中的事务不会生效,因为这是一个自调用,不经过 Spring 的代理机制。

解决办法:

将事务方法抽取到另一个类中,或者通过依赖注入的方式调用。

@Service
public class MyService {

    @Autowired
    private MyService self;

    public void nonTransactionalMethod() {
        // 使用 self 调用,事务才能生效
        self.transactionalMethod();
    }

    @Transactional
    public void transactionalMethod() {
        // 事务逻辑
    }
}

2. 事务方法不是 public 修饰

Spring 的事务管理是基于代理的,它只会对 public 方法进行代理。对于 privateprotected、或者 package-private 的方法,Spring 事务不会生效,因为代理类无法拦截对这些方法的调用。

示例:

@Transactional
private void transactionalMethod() {
    // 事务逻辑
}

在这种情况下,事务不会生效,因为 transactionalMethod() 不是 public 方法。

解决办法:

确保事务方法是 public 的。

@Transactional
public void transactionalMethod() {
    // 事务逻辑
}

3. 未被 Spring 管理的对象

只有被 Spring 容器管理的 Bean,事务代理才能起作用。如果方法是在一个非 Spring 管理的类中调用的,即使添加了 @Transactional 注解,事务也不会生效。

示例:

public class ExternalClass {
    @Transactional
    public void transactionalMethod() {
        // 事务逻辑
    }
}

如果 ExternalClass 不是由 Spring 容器托管,transactionalMethod() 上的事务将不起作用。

解决办法:

确保事务相关的 Bean 是通过 Spring 管理的,即确保它们是由 Spring 容器注入的,例如通过 @Service@Component 标注的类。

4. 异常类型不匹配导致事务回滚失败

Spring 的默认事务管理策略是只在遇到 unchecked 异常(RuntimeException)Error 时回滚事务。如果方法抛出了一个 checked 异常(如 IOException),事务不会回滚。

示例:

@Transactional
public void transactionalMethod() throws Exception {
    // 如果抛出 checked 异常,事务不会回滚
    throw new Exception("Checked Exception");
}

在上述示例中,方法抛出的是一个 Exception(checked 异常),默认情况下,Spring 不会回滚事务。

解决办法:

可以通过 rollbackFor 属性明确指定哪些异常需要触发事务回滚:

@Transactional(rollbackFor = Exception.class)
public void transactionalMethod() throws Exception {
    // 事务会回滚
    throw new Exception("Checked Exception");
}

5. 传播类型使用不当

事务传播类型决定了当一个事务方法调用另一个事务方法时,事务如何传播。如果传播类型配置不当,可能导致事务行为与预期不一致,甚至事务失效。

示例:

使用 Propagation.NOT_SUPPORTEDPropagation.REQUIRES_NEW 传播类型时,如果子事务方法被配置为不支持或需要新的事务,可能会导致当前事务的逻辑与原始事务隔离,无法实现事务传播效果。

@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void nonTransactionalMethod() {
    // 该方法不会加入现有事务,事务逻辑不会生效
}

解决办法:

根据业务需求选择正确的传播类型,例如使用 Propagation.REQUIRED 让子方法加入当前事务。

6. 数据库本身不支持事务

并非所有数据库都支持事务操作。比如,某些 NoSQL 数据库(如 MongoDB、Cassandra)对事务的支持是有限的。如果数据库不支持事务,即使在代码中配置了事务管理,事务也不会生效。

解决办法:

确保所使用的数据库支持事务,并正确配置数据库连接。

7. 使用了不支持事务的操作

某些数据库操作或框架方法不支持事务。比如,批量操作或者直接使用 JdbcTemplate 进行大批量数据插入时,可能不会受到事务控制的影响。

解决办法:

确保使用支持事务管理的数据库操作工具,如 JPA、Hibernate,或者正确配置 JdbcTemplate

8. 事务管理器未正确配置

Spring 事务管理依赖于 PlatformTransactionManager,如果没有正确配置事务管理器,事务也不会生效。常见问题包括未正确配置数据源或没有配置事务管理器。

解决办法:

确保 PlatformTransactionManager 正确配置,并且事务管理器与数据源绑定一致。

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}

9. 代理模式下的事务不生效

Spring 使用动态代理(JDK 动态代理或 CGLIB)来实现 AOP。如果使用了 JDK 动态代理,它只对接口的方法进行代理,导致如果在实现类上直接调用方法,事务可能不生效。

解决办法:

如果没有接口,确保 @Transactional 注解的类使用的是 CGLIB 代理,而不是 JDK 代理。

@EnableTransactionManagement(proxyTargetClass = true) // 强制使用 CGLIB 代理

总结

事务失效的原因主要包括自调用、方法访问权限、异常处理不当、传播类型选择错误等。在实际开发中,务必确保事务方法正确配置,并且在调用方法时遵循 Spring AOP 的代理机制,避免事务失效。

标签:解决办法,事务,调用,Spring,传播,transactionalMethod,public
From: https://blog.csdn.net/hyc010110/article/details/143163534

相关文章

  • 【JAVA毕业设计】基于Vue和SpringBoot的课程作业管理系统
    本文项目编号T023,文末自助获取源码\color{red}{T023,文末自助获取源码}......
  • 【JAVA毕业设计】基于Vue和SpringBoot的大学生入学审核系统
    本文项目编号T022,文末自助获取源码\color{red}{T022,文末自助获取源码}......
  • Spring Boot框架:打造可扩展的论坛网站
    4系统概要设计4.1概述本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示:图4-1系统工作原理图4.2系统结构本系统......
  • SpringBoot 单元测试 - 登录认证在 Spring Boot 上的标准单元测试写法。
    ......
  • Spring Boot论坛网站:开发、部署与管理
    3系统分析3.1可行性分析通过对本论坛网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。3.1.1技术可行性本论坛网站采用SSM框架,JAVA作为开发语言,是基于WEB平台的B/S架构系统。(1)Java......
  • springboot优质鸭梨的培育管理系统-计算机毕业设计源码92834
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1数据流程2.2.2业务流程2.3 系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4 系统用例分析2.5本章小结3 系统......
  • Spring Boot环境下论坛网站的架构与优化
    3系统分析3.1可行性分析通过对本论坛网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。3.1.1技术可行性本论坛网站采用SSM框架,JAVA作为开发语言,是基于WEB平台的B/S架构系统。(1)Java......
  • springboot献血管理平台-计算机毕业设计源码94158
    摘 要随着社会的快速发展和医疗技术的不断进步,献血作为一种重要的公益行为,对于保障医疗用血的需求和挽救生命具有不可替代的作用。然而,传统的献血管理方式往往存在着效率低下、信息不透明、数据难以统计等问题。为了解决这些问题,提高献血管理的效率和质量,基于Java编程语言,设......
  • springboot二手汽车交易平台-计算机毕业设计源码82053
    目录1绪论1.1研究背景1.2研究意义1.3国内外研究现状2 二手汽车交易平台系统分析2.1可行性分析2.2系统流程分析2.3 功能需求分析2.4性能需求分析3二手汽车交易平台概要设计3.1 系统体系结构设计3.2总体功设计3.3子模块设计设计3.4数据库......
  • springboot图书销售管理系统-计算机毕业设计源码38008
    摘要JavaEE的图书销售管理系统是一个基于JavaEE技术开发的综合性图书销售和管理平台,旨在帮助图书店管理者提高图书销售效率和管理水平。系统主要功能包括网站公告,图书资讯,图书中心,商城管理,图书信息,个人首页,图书信息,商品中心,订单配送等。图书信息管理模块可以实现图书的添加......