`
heroliuxun
  • 浏览: 23954 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring 声明式事务中try catch捕获异常

阅读更多
最近遇到这样的问题,使用spring时,在业务层需要捕获异常(特殊需要),当前一般情况下不需要这样做的。具体如下:
在ServiceA类中有method1,在该方法中调用另一个ServiceB类的method2方法时(假定该方法抛出异常),method1方法捕获该异常但是没有向上抛出。spring提示:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

以下是ServiceA的示例代码
@Transactional(rollbackFor = Throwable.class)//默认事务传播方式required
public Class ServiceA {
   
    @Autowired 
    private Dao dao;

    @Autowired 
    private ServiceB serviceB;  // 注入另一Service Bean
   
    public void method1() {

        dao.insert(vo);  // 保存ServiceA的vo对象
        try {
            serviceB.method2(vo); // 保存ServiceB的vo对象
        } catch (CustomException e) {
            // 捕获自定义异常,但是没有向上抛出
        }

    }
}


以下是ServiceB的示例代码
@Transactional(rollbackFor = Throwable.class)//默认事务传播方式required
public Class ServiceB {
   
    @Autowired 
    private Dao dao;
   
    public void method2() throws CustomException {

        dao.insert(vo);  // 保存ServiceA的vo对象
    }
}

出现以上原因是spring执行method1方法时,开启一个新的事物,当调用method2方法时,当method2方法加入到method1方法的当前事务,当method2抛出异常,spring标记事务为回滚状态,method1方法捕获该异常,但没有抛出,spring会提交method1的事务,但spring发现该事务已经标记为回滚状态,而代码中却要提交事务,所以才会抛出以上的异常。


解决的方法:在ServiceB的method2方法上注解,告诉spring当该方法抛出自定义异常CustomException时,不要回滚事务,这样当该方法抛出异常时,spring不会标记事务为回滚状态。
@Transactional(noRollbackFor=CustomException.class)
public void method2() throws CustomException{
}
  • 大小: 6.5 KB
分享到:
评论
2 楼 雪山肥大象 2018-04-19  
奇怪的是,如果把 serviceB.method2(vo)这method2方法放到ServiceA中,就不会报这个异常:org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
1 楼 穿围裙的程序员 2015-04-27  
@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class)
public void testC() throws Exception{
Random random = new Random();
dmo.update("insert into chh_test(id,name,code) values(?,?,?)",random.nextInt(5),"ccc",random.nextInt());
int i = 2/0;
}


public void testD() throws Exception{
testC();
}

@Test
public void testE(){
try {
testD();
} catch (Exception e) {
e.printStackTrace();
}
}

在用Junit运行方法 testE() 也不回滚是怎么回事?

我把Transactional加在了testC(),不是应该在 testC()抛异常的时候就回滚么?

相关推荐

    spring 自定义事务管理器,编程式事务,声明式事务@Transactional使用

    本教程将深入探讨如何在Spring中实现自定义事务管理器、编程式事务处理以及声明式事务`@Transactional`的使用。 首先,让我们了解事务管理的基本概念。事务是一组数据库操作,这些操作要么全部执行,要么全部回滚,...

    spring编程式和声明式事务管理

    在Spring中,声明式事务管理是基于AOP(面向切面编程)实现的。我们只需要在方法上添加@Transactional注解,就可以让Spring自动进行事务管理。例如: ```java @Service public class UserService { @Transactional...

    使用MyBatisPlus+Spring实现声明式事务

    与编程式事务管理(在代码中显式地开始、提交和回滚事务)不同,声明式事务管理允许我们在配置文件或注解中定义事务边界,从而让Spring框架自动处理事务的生命周期。这种方式更加简洁且易于维护。 1. **集成...

    spring编程式事务与声明式事务详解[参照].pdf

    Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 **编程式事务管理**是通过编写代码来显式地管理事务的开始、提交、回滚等操作。在Spring中,可以使用PlatformTransactionManager接口的实现...

    完美解决Spring声明式事务不回滚的问题

    完美解决Spring声明式事务不回滚的问题 在实际应用中,Spring声明式事务管理是非常常见的,但是有...解决Spring声明式事务不回滚的问题需要我们了解事务管理的机制和原理,并避免在业务逻辑中使用try...catch异常。

    Spring事务详细讲解

    Spring 声明式事务让我们从复杂的事务处理中得到解脱,使得我们再也无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。再也无需要我们在与事务相关的方法中处理大量的 try…catch…finally 代码。 事务...

    声明式事务处理(源代码)

    本资源包含两个文件:“Spring声明式事务处理.wrf”和“testtrans”,很可能是示例代码或者测试用例,用于演示如何在Java应用中使用Spring进行声明式事务处理。 首先,让我们深入理解声明式事务处理的概念。声明式...

    Spring框架的事务管理应用分析.doc

    声明式事务管理通过配置(如XML或注解)来定义事务边界,无需在代码中显式处理。它更加简洁,降低了出错概率,且易于维护。Spring支持基于注解的事务管理,例如在方法上添加`@Transactional`注解来指定事务行为。 ...

    spring学习笔记(十五)-编程式事务例子

    在实际开发中,我们通常使用声明式事务管理,它基于AOP(面向切面编程)来简化事务处理。然而,有时为了更细粒度的控制或者在特定场景下,我们可能需要采用编程式事务管理。 首先,了解事务的四大特性(ACID)是必...

    Spring 框架的事务管理及应用

    声明式事务管理是通过配置的方式设置事务的边界,通常通过Spring的`@Transactional`注解或者XML配置来实现。这种方式比编程式事务管理更为简洁和方便。 **示例:传统的JDBC事务管理** 在使用JDBC进行数据操作时,...

    spring 事务传播 demo

    通过声明式事务管理,我们只需在方法上添加@Transactional注解,而无需编写手动的try-catch-finally代码块来管理事务。 在实际应用中,我们还应考虑事务的隔离级别、事务超时和回滚规则等参数,以确保数据的一致性...

    spring 的3种事务配置方式

    本文将详细介绍Spring中的三种事务配置方式:编程式事务管理、声明式事务管理以及基于注解的事务管理。 **1. 编程式事务管理** 编程式事务管理是通过编程的方式手动控制事务的开始、提交、回滚等操作。主要使用`...

    spring_如何管理事务的

    Spring支持两种类型的事务管理方式:编程式事务管理和声明式事务管理。 #### 二、编程式事务管理 编程式事务管理允许开发人员通过编程的方式直接控制事务的开始、提交或回滚。这种方式相对灵活,但也存在一些缺点...

    Spring事务管理4种方式

    2. **声明式事务管理**:这是Spring最常用的方式,通过在配置文件或注解中声明事务属性,由Spring自动进行事务的生命周期管理。声明式事务分为基于XML配置和基于注解两种: - XML配置: ```xml *" ...

    spring+mybatis的编码式事务

    因此,在实际开发中,推荐使用基于注解的声明式事务,通过`@Transactional`注解简化事务管理,让代码更清晰、易于维护。然而,了解和掌握编码式事务有助于理解Spring事务管理的底层原理,对于解决特定场景的问题或...

    spring高级编程详解

    #### 二、Spring声明式事务简介 Spring框架的声明式事务管理主要通过AOP(面向切面编程)来实现。这种方式允许开发者通过简单的注解或XML配置来定义事务边界,而无需显式地编写事务管理代码。Spring的声明式事务...

    spring编程式事物

    编程式事务管理是指在代码中显式地控制事务的开始、提交、回滚等操作,而声明式事务管理则是通过配置或注解来定义事务边界,更加简洁且易于维护。 标题"spring编程式事物"主要关注的是编程式事务管理。这种方式允许...

    Spring事务管理A方法内部调用B方法的回滚问题测试代码

    在这个例子中,我们可能关注的是声明式事务管理,因为它是Spring中最常用的方式。 首先,我们需要在Spring配置文件中启用事务管理器,例如使用`<tx:annotation-driven>`标签。这将扫描带有@Transactional注解的方法...

Global site tag (gtag.js) - Google Analytics