Spring Transaction Doesn't Rollback

ぃ、小莉子 提交于 2019-12-04 07:32:50

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):

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.

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.

The solution in your case would be calling saveOrderDetails(customerOrder); as proxyBean.saveOrderDetails(customerOrder); Where proxybean is the Object on whichhandleIncomingOrders` is being called.

If CustomerService is singleton (Defualt scope) it can be as simple as adding below code to the Service class. (adding a self reference as autowired)

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

and in the Method use it as

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

If its scope is Prototype the one of possible simple solution will be as follows.

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

And where you are calling handleIncomingOrders use changes suggested in below code.

    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. 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!