春季交易不会回滚 [英] Spring Transaction Doesn't Rollback

查看:108
本文介绍了春季交易不会回滚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个春季交易回滚问题,回滚似乎不起作用.
在用@Transactional注释的服务层方法中,我调用了三个不同的DAOImpl类以插入3条记录.
中间的插入从第4个表进行get操作以填充描述字段,但此操作失败.我希望第一个插入回滚,但是似乎没有发生.
几点:

We have a Spring Transaction rollback issues, where rollback doesn't seems to be working.
Within my service layer method which is annotated with @Transactional I call three different DAOImpl classes to insert 3 records.
The middle insert do a get from a 4th table to populate a description field but this get failed. I expect the first insert to rollback but it doesn't seems to be happening.
Few Points:

  1. 'Get'方法引发运行时异常
  2. 我们正在使用applicationContext.xml中定义的org.springframework.jdbc.datasource.DataSourceTransactionManagerMySQL datasource.在Beans.xml中创建Bean,然后将其导入ApplicationContext.xml
  3. DAO
  4. 中没有@Transactional批注
  5. 我们在applicationContext.xml
  6. 中再次使用了<tx:annotation-driven transaction-manager="transactionManager"/>
  7. 我们正在使用Spring 3.1
  1. The 'Get' method throws a Runtime Exception
  2. We are using org.springframework.jdbc.datasource.DataSourceTransactionManager and MySQL datasource defined in applicationContext.xml. Beans are created in Beans.xml which is imported into ApplicationContext.xml
  3. No @Transactional annotation in DAO layer
  4. We have used <tx:annotation-driven transaction-manager="transactionManager"/> again in applicationContext.xml
  5. We are using Spring 3.1

更新:

代码段....

Service Class-这有点类似于我的....我在使用@Autowired和不使用@Autowired的情况下进行了测试.在服务类中调用事务启用方法.

Service Class- This is somthing similar to what I have .... I tested with and without @Autowired. The transaction enable method is called within the service class.


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);
            }

    }
}

有什么主意吗? 谢谢.

Any idea? Thanks.

推荐答案

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

The default behaviour of @Transactional is that transactional behaviour is added with a proxy around the object (the CustomerService in your example). From the reference docs (scroll down):

在代理模式(默认)下,仅拦截通过代理传入的外部方法调用.这意味着,实际上,即使被调用的方法标记有@Transactional,自调用实际上也不会导致运行时实际事务在目标对象中调用目标对象的另一种方法.

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.

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

In your example, an external call to the handlingIncomingOrders() passes through the proxy and hits the target object (an instance of the CustomerService). However, the subsequent call to saveOrderDetails() is a normal method call inside the target object, thus the transactional behaviour in the proxy is never invoked. However, if the saveOrderDetails() was called from another class, you will find that the transactional behaviour will work as expected.

这篇关于春季交易不会回滚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆