Я добавил комментарий к Spring Билет на улучшение по этому вопросу. Я тоже здесь скопирую:
Я обошел эту проблему, преобразовав все сервисные методы, которые были настроены декларативно, как это
@Transactional(propagation = REQUIRES_NEW)
public Object doSmth() {
// doSmthThatRequiresNewTx
}
для использования TransactionTemplate
вместо:
private TransactionTemplate transactionTemplate;
public Object doSmth() {
return transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus status) {
// doSmthThatRequiresNewTx
}
});
}
В тестах я настраиваю поведение распространения transactionTemplate
на PROPAGATION_REQUIRED
, в реальном приложении я настраиваю поведение распространения transactionTemplate
на PROPAGATION_REQUIRES_NEW
. Работает как положено. Ограничение этого обходного пути заключается в том, что при тестировании невозможно утверждать, что внутренняя транзакция не откатывается в исключительном сценарии.
Другим решением было бы явное удаление всего, что doSmth()
делает в базе данных в тестируемом методе @AfterTransaction
. Этот SQL «delete» будет запущен в новой транзакции, так как в противном случае его результаты будут регулярно откатываться из-за поведения TransactionConfiguration
по умолчанию Spring.