当前位置: 首页 > 知识库问答 >
问题:

Spring事务不会回滚

慕容铭
2023-03-14

我们有一个Spring事务回滚问题,其中回滚似乎不起作用
在用@Transactional注释的服务层方法中,我调用三个不同的DAOImpl类来插入3条记录
中间插入从第四个表执行get以填充描述字段,但此get失败。我希望第一次插入会回滚,但它似乎没有发生
几点:

  1. 获取方法抛出运行时异常
  2. 我们使用org.springframework.jdbc.datasource.DataSourceTransactionManagerMySQL数据源中定义的应用ontext.xml。Bean是在Beans.xml中创建的,它被导入到Application ationContext.xml
  3. DAO
  4. 中没有 @Transactional注释
  5. 我们已经使用了

更新:

代码片段......

服务类-这与我所拥有的类似。。。。我测试了是否有@Autowired。事务启用方法在服务类中调用。


public class CustomerService {

    //@Autowired
    CustomerOrderDAO customerOrderDAOImpl;
    //@Autowired
    CustomerItemDAO customerItemDAOImpl;
    //@Autowired
    CustomerPromotionDAO customerPromotionDAOImpl;
    //@Autowired
    PromotionDAO promotionDAOImpl;

    //other variables


    public CustomerOrder handleIncomingOrders(CustomerOrder customerOrder) {
        try {
            saveOrderDetails(customerOrder);
            .....
            return customerOrder;
        } catch (Exception e) //TO-DO catch proper exception 
        {
            //Send error response
            .......
            return customerOrder;
        }
    }

    @Transactional
    public void saveOrderDetails(CustomerOrder customerOrder) throws Exception {
            customerOrderDAOImpl.create(customerOrder);
            ....
            while (promotionsIterator.hasNext()) {
                customerPromotion.setPromotionName(promotionDAOImpl.getName(customerOrder.getPromotionId));
                customerPromotionDAOImpl.create(customerPromotion);
            }
            ......
            while (customerItemIterator.hasNext()) {
                customerItemDAOImpl.create(customerItem);
            }

    }
}

任何想法?谢谢。


共有2个答案

孙佑运
2023-03-14

在您的情况下,解决方案将调用SaveOrder细节(客户订单);作为proxyBean.save订单细节(客户订单);其中proxybean是调用handleIncomingOrders'的对象。

如果CustomerServicesingleton(定义范围),则只需将以下代码添加到服务类即可。(将自参考添加为自动连线)

//@Autowired
CustomerService customerService; // As this is injected its a proxy

在方法中,将其用作

 public CustomerOrder handleIncomingOrders(CustomerOrder customerOrder) {
    try {
        customerService.saveOrderDetails(customerOrder);
        .....
        return customerOrder;
    } catch (Exception e) //TO-DO catch proper exception 
    {
        //Send error response
        .......
        return customerOrder;
    }
  }

如果其范围为原型,则可能的简单解决方案如下。

public CustomerOrder handleIncomingOrders(CustomerOrder customerOrder, CustomerService customerService) {
    try {
        customerService.saveOrderDetails(customerOrder);
        .....
        return customerOrder;
    } catch (Exception e) //TO-DO catch proper exception 
    {
        //Send error response
        .......
        return customerOrder;
    }
  }

在调用handleIncomingOrders的地方,请使用下面代码中建议的更改。

    bean.handleIncomingOrders(customerOrder); //Suppose this is old code 
Change it to 
    bean.handleIncomingOrders(customerOrder, bean);// THough it appears as we are sending reference to `THIS` as parameter whcihc can be unnecessary, in case of `Proxy`while inside your method `this` and `Passed reference` will point to different Obejects. 
司空赞
2023-03-14

@Transactional的默认行为是在对象周围添加了代理的事务性行为(示例中的CustomeService)。从参考文档(向下滚动):

在代理模式(这是默认模式)下,只截获通过代理传入的外部方法调用。这意味着自调用,实际上是目标对象内调用目标对象另一个方法的方法,即使调用的方法标记为@Transactional,在运行时也不会导致实际事务。

在您的示例中,对handlingIncomingOrders()的外部调用通过代理并命中目标对象(CustomerService的实例)。但是,对saveOrderDetails()的后续调用是目标对象内部的正常方法调用,因此永远不会调用代理中的事务行为。但是,如果从另一个类调用了saveOrderDetails(),您会发现事务行为将按预期工作。

 类似资料:
  • 如果我没有捕捉到运行时异常,我就不会得到hibernate异常(不要刷新会话..)

  • 这很好,但并不总是在代码中抛出运行时异常。因此,我挖掘并发现如下所示的rollbackFor; 现在,我必须更改所有代码,以使用RollBackfor更改@Transactional。但是还有其他方法可以将所有@transaction advice属性更改为rollbackFor=exception.class吗?

  • 问题内容: 我正在使用TestNG 6.9.9来构建回归测试环境。但是遇到使用JUnit时从未遇到过的问题。在我看来,当每个测试用例完成时,如果测试方法在与调用方法相同的事务上下文中运行,则默认情况下将自动回滚每个数据的更改。但这似乎不是事实,而且我无法找出我的代码中是否有任何错误。请帮帮我。pom.xml中的属性,指示框架的版本 显然,它们都是最新的。 我的测试课: 创建一个实体实例,然后调用c

  • -ZJ 以下是我在Application.Properties中的数据源设置: