0

I have a method that I annotated with @Transactional(propagation = Propagation.REQUIRES_NEW). It is indirectly called from a method with @Transactional(propagation = Propagation.NOT_SUPPORTED) which should interrupt every existing transaction for the methods it calls. Interrupting the transaction works fine. My problem is, that Propagation.REQUIRES_NEW does not create a new transaction as I would need it to.

I am however able to do manual transaction management in which case the whole construct works as expected. Yet I would really like to avoid the manual transaction management.

So my question is, how can I use Propagation.REQUIRES_NEW within Propagation.NOT_SUPPORTED to create new transactions as needed?


Code as requested:

Intitial call from test class:

service.loadData(false);

Service is an interface as following:

@Transactional
public interface DataService {

    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    void loadData(boolean singleDayOnly);

    void someOtherMethodWithDefaultTransaction();
}

Service implementation calls controller:

@Override
public void loadData(boolean singleDayOnly) {
    controller.loadData(singleDayOnly);
}

Controller is an interface as well but without any @Transactional.

Controller implementation:

@Override
public void loadData(boolean singleDayOnly) {
    List<Data> data = getAllForRequest();
    for (Data entry : data) {
        someMethodWithTransaction(entry);
    }
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
private List<Data> getAllForRequest() {
    //dao.getHibSession().beginTransaction();
    List<Data> l = securityDailyDataDao.getAllForRequest();
    //dao.getHibSession().getTransaction().commit();
    return l;
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void someMethodWithTransaction(SecurityDailyData entry) {
    //securityDailyDataDao.getHibSession().beginTransaction();
    DTO dto = ..getDTO();
    entry.setCode(dto.getID());

    securityDailyDataDao.getHibSession().merge(entry);
    //securityDailyDataDao.getHibSession().getTransaction().commit();
}

This is how I would like it to be. But no transaction get created which is the reason I have to create them manually

XtremeBaumer
  • 6,275
  • 3
  • 19
  • 65
  • Can you show some example code on how and where it's called? – Kayaman Jul 12 '18 at 09:07
  • @Kayaman add the code, I hope its understandable – XtremeBaumer Jul 12 '18 at 09:16
  • You mean the `loadData` inside the controller? – XtremeBaumer Jul 12 '18 at 09:19
  • Yeah, `loadData` calling `someMethod` will bypass the proxy, which means it will bypass any AOP that would handle the annotations. – Kayaman Jul 12 '18 at 09:20
  • Alright, I think I get the problem I have. Is there any way around it without creating a separate class? – XtremeBaumer Jul 12 '18 at 09:22
  • TL;DR of the duplicate: It's possible to change the default behaviour so that the code in the example would work, by using load time weaving instead of AOP proxies. However, it'll probably be easier to just work around it. – Kayaman Jul 12 '18 at 09:23
  • 1
    Creating a separate class is the easiest way around it without having to configure things and change the default behaviour. – Kayaman Jul 12 '18 at 09:24

0 Answers0