2
votes

I have a method with @Transaction calling a method with @Transaction( Propagation.REQUIRES_NEW) . Both the transactions are rolled back in case of exception in the parent method.

Parent Transaction:

@Transactional(propagation = Propagation.REQUIRED)
public void test() {
    SampleClassParent sampleClassParent = new SampleClassParent();
    sampleClassParent.setAddressId(2545L);
    sampleClassParent.setUserId(21660742L);
    getBaseDao().saveOrUpdate(sampleClassParent);
    newTransaction();

    // getting an exception purposefully
    User user = null;
    user.getId(); // Will throw a null pointer exception
}

Nested Transaction:

@Transactional(propagation = Propagation.REQUIRES_NEW)
private void newTransaction(){
    SampleClassNested sampleClassNested = new SampleClassNested();
    sampleClassNested.setCityId(15747L);
    sampleClassNested.setStoreId(5L);
    getBaseDao().saveOrUpdate(sampleClassNested);
}

SaveOrUpdate Method: (uses hibernate 3.3.2)

  // Wrapper around hibernate method
  public void saveOrUpdate(Object entity, boolean delayCommit) {
      getSessionFactory().getCurrentSession().saveOrUpdate(entity);
  }

All entries are created successfully when no exception is thrown. SampleClassParent and SampleClassNested are Hibernate Entity classes.

Here both the transactions are rolled back, but Ideally, Propagation.REQUIRES_NEW should suspend the existing transaction and create a new transaction. Why?

1
@Transactional doesn't work on a private method. See stackoverflow.com/questions/4396284/…. Even for public methods, it only works when called from outside of your class. So your outside caller will have to make two calls.David Lavender
The result is the same for both, public and private methods. The issue is that I have nested transactions. The outside method only calls the parent transaction. Also, If I call it using an outside method, will it not effectively mean the same thing (nested transactions)?Abhinav

1 Answers

0
votes

From the provided code I would think it's because you call directly the method newTransaction(). For transaction management could be processed you have to give the container a chance to intercept the method call. That could be done by injection the bean and by calling the method from that injection point, kind of bean.newTransaction().