jamesdeath123
jamesdeath123

Reputation: 4608

What happen on Transaction.rollback in nested session/transactions?

Consider this two classes: EmployeeDetailDAOImpl and EmployeeDAOImpl. Assume if I want to create a new employee, I should also create a new record for EmployeeDetail.

Given the below implementation, I wonder if the outer transaction(EmployeeDAOImpl's tx) is rolled back due to any exceptions happened after the detailDAO.create(employeeId) call, will the transaction of new EmployeeDetail be rolled back as well?

public class SessionHandler {
    public static getSession() {
        return Configuration.buildSessionFactory().openSession(); //ignore the isConnected or other exception handling for now
    }
}

public class EmployeeDetailDAOImpl {
    public void create(Serializable employeeId) {
        Session session = SessionHandler().getSession();
        Transaction tx = session.beginTransaction();
        try {
            EmployeeDetail detail = new EmployeeDetail(employeeId);
            session.save(detail );
        } catch (Exception e) {
            if (tx!= null) {
                tx.rollback;
            }
        }
        session.close();
    }
}

public class EmployeeDAOImpl {
    public void add(String name) {
        Session session = SessionHandler().getSession();
        Transaction tx = session.beginTransaction();
        try {
            Employee employee = new Employee(name);
            Serializable employeeId= session.save(employee);
            EmployeeDetailDAOImpl detailDAO = new EmployeeDetailDAOImpl();
            detailDAO.create(employeeId);
            //more things here, that may through exceptions.
        } catch (Exception e) {
            if (tx!= null) {
                tx.rollback;
            }
        }
        session.close();
    }
}

Upvotes: 0

Views: 146

Answers (3)

Kurt Du Bois
Kurt Du Bois

Reputation: 7655

Actually, none of the given answers is 100% correct.

It depends on the calling party/service.

If you are calling the methods from an EJB, you will have 1 transaction covering both method calls. That way, the transaction will roll back both operations in case of an exception. Reason behind this is that every method in EJB is transaction Required, unless specified otherwise in the annotation or ejb deployment descriptor.

If you are using spring or any other DI framework, then it depends on your configuration. In a normal setup, your calling transaction will be suspended, since the JPA EJB will create its own transaction. You can however use the JTATransactionManager (As specified here) to make sure that both your EJB and your Spring bean share the same transaction.

If you call the JPA methods from a POJO, then you will have to take care of the JTA transaction handling yourself.

Upvotes: 1

Vaibs
Vaibs

Reputation: 1606

You are creating two different transaction for each method.Hence rollback can not happen.

To rollback the transaction you require the propogation in Transaction.

You need to write the code like below::

@Transactional(propagation=Propagation.REQUIRED)
public void testRequired(User user) {
  testDAO.insertUser(user);
  try{
    innerBean.testRequired();
  } catch(RuntimeException e){
    // handle exception
  }
}

Below is link for more information of Propogation. http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/transaction/annotation/Propagation.html

http://www.byteslounge.com/tutorials/spring-transaction-propagation-tutorial

Upvotes: 0

Monish Sen
Monish Sen

Reputation: 1888

Yes, it will rollback the entity Employee as well. It doesn't even depend on whether the other entities are related. It depends on the scope of the transaction, which here includes both Employee and EmployeeDetails

Upvotes: 0

Related Questions