1

I am bit confused about spring transaction management's propagation mechanism specially about REQUIRES_NEW. As documentation here

PROPAGATION_REQUIRES_NEW, in contrast to PROPAGATION_REQUIRED, uses a completely independent transaction for each affected transaction scope. In that case, the underlying physical transactions are different and hence can commit or roll back independently, with an outer transaction not affected by an inner transaction’s rollback status.

What I understood is when any method annotated with @Transactional(propagation=Propagation.REQUIRES_NEW), always new physical transaction is created and if it rollbacks it will not effect outer transaction.

Now I have below scenario where I am calling two transactional methods one is with default propagation level and other with requires new propagation. Now when I throw RuntimeException from second method It should rollback only that transaction instead It is rolling back the whole transaction. Below is the sample code.

@Service
public class UserService {

@Autowired
private UserRepository userRepository;


@Transactional
public void firstTransaction() {
    User user = new User();
    user.setFirstname("Monica");
    user.setLastname("Galler");

    userRepository.save(user);

    secondTransaction();
}

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void secondTransaction() {
    User user = new User();
    user.setFirstname("Rachel");
    user.setLastname("Green");

    userRepository.save(user);

    throw new RuntimeException("thown exception!!");
}

}

and class from where I am calling this method

@Component
public class TxHandler {

@Autowired
private UserService userService;

public void handleTransaction() {
    userService.firstTransaction();
}

}

Please let me know am I missing something here ?

Here are the logs printed for transaction manager

2018-06-17 13:37:52.553 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Creating new transaction with name [com.example.SpringTutorial.service.UserService.firstTransaction]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2018-06-17 13:37:52.554 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Opened new EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
2018-06-17 13:37:52.561 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@2e766822]
2018-06-17 13:37:52.582 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
2018-06-17 13:37:52.582 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2018-06-17 13:37:52.674 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Found thread-bound EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.example.SpringTutorial.entity.User#26]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=1} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for JPA transaction
2018-06-17 13:37:52.674 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Participating in existing transaction
2018-06-17 13:37:52.680 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Initiating transaction rollback
2018-06-17 13:37:52.680 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Rolling back JPA transaction on EntityManager [SessionImpl(PersistenceContext[entityKeys=[EntityKey[com.example.SpringTutorial.entity.User#26], EntityKey[com.example.SpringTutorial.entity.User#27]],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=2} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
2018-06-17 13:37:52.683 DEBUG 903 --- [           main] o.s.orm.jpa.JpaTransactionManager        : Closing JPA EntityManager [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] after transaction
hiren
  • 1,742
  • 13
  • 20
  • Also see the documentation: https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#tx-decl-explained – JB Nizet Jun 17 '18 at 09:13

0 Answers0