Я немного смущен механизмом распространения управления транзакциями Spring, особенно в отношении REQUIRES_NEW
. В качестве документации здесь < / а>
PROPAGATION_REQUIRES_NEW
, в отличие отPROPAGATION_REQUIRED
, использует полностью независимую транзакцию для каждой затронутой области транзакции. В этом случае базовые физические транзакции различны и, следовательно, могут фиксироваться или откатываться независимо, при этом на внешнюю транзакцию не влияет статус отката внутренней транзакции.
Я понял, что когда любой метод, помеченный знаком @Transactional(propagation=Propagation.REQUIRES_NEW)
, всегда создается новая физическая транзакция, и если он откатывается, это не повлияет на внешнюю транзакцию.
Теперь у меня есть сценарий ниже, в котором я вызываю два транзакционных метода: один с уровнем распространения по умолчанию, а другой требует нового распространения. Теперь, когда я выбрасываю RuntimeException
из второго метода, он должен откатить только эту транзакцию, вместо этого он откатывает всю транзакцию. Ниже приведен пример кода.
@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!!");
}
}
и класс, откуда я вызываю этот метод
@Component
public class TxHandler {
@Autowired
private UserService userService;
public void handleTransaction() {
userService.firstTransaction();
}
}
Пожалуйста, дайте мне знать, я что-то упускаю?
Вот журналы, напечатанные для менеджера транзакций
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