Сохранение не работает, когда обрабатывается исключение - PullRequest
0 голосов
/ 20 декабря 2018

Я сталкиваюсь с ситуацией, даже не могу найти способ отладки.

У меня есть следующие spring-data репозитории:

IntegrationLogRepository

public interface IntegrationLogRepository extends PagingAndSortingRepository<IntegrationLog, Long> {

}

FooRepository

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> {

}

И в моей бизнес-логике у меня есть что-то вроде следующего:

IntegrationLog log = new IntegrationLog();
log.setTimestamp(new Date());

try {
    Foo foo = new Foo();

    // Build the Foo object...

    fooRepository.save(foo);
    log.setStatus("OK");
} catch (Exception e) {
    log.setStatus("NOK");
} finally {
    integrationLogRepository.save(log);
}

Когда интеграция работает нормально,log сохраняется со статусом OK.Все отлично.Но когда у меня есть исключение, по какой-то причине integrationLogRepository.save(log) ничего не делает.Я ничего не имею в виду НИЧЕГО: исключение не выдается, и я не вижу ни одного запроса гибернации, выполняемого на моей консоли WebLogic.Журнал не сохраняется ...

Есть идеи, почему это происходит?

Ниже приведены мои зависимости:

compile 'org.springframework.boot:spring-boot-starter-data-rest'
compile 'org.springframework.boot:spring-boot-starter-security'
compile "org.springframework.boot:spring-boot-starter-web-services"
runtime 'org.springframework.boot:spring-boot-devtools'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'
compile "org.springframework.boot:spring-boot-starter-websocket"
compile 'javax.servlet:javax.servlet-api:3.1.0'
compile 'org.hibernate:hibernate-core:5.1.16.Final'
compile 'org.hibernate:hibernate-validator:5.2.3.Final'
compile 'org.hibernate:hibernate-entitymanager:5.1.0.Final'

Запуск в Spring Boot 1.5.15.RELEASE,Java 1.7 и WebLogic 12.1.3.

Спасибо!

1 Ответ

0 голосов
/ 20 декабря 2018

Исключение также откатывает сохранение журнала интеграции.Если вы хотите сохранить журнал, вы должны указать отдельную транзакцию при сохранении.

Абстрагируйте репозиторий журнала для службы, а в методе службы, который сохраняет журнал, добавьте транзакцию, которая создает новую транзакцию..

@Service
public class IntegrationLogService {

    private final IntegrationLogRepository logRepository;

    @Autowired
    public IntegrationLogService(IntegrationLogRepository logRepository) {
        this.logRepository = logRepository;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void save(Log log) {
        this.logRepository.save(log);
    }
}

В вашей компании замените

finally {
    integrationLogRepository.save(log);
}

на

finally {
    integrationLogService.save(log);
}

Изменить

Зачем устанавливать @Transactional(propagation = Propagation.NOT_SUPPORTED) на бизнес-уровне работал?

Чтобы понять, почему он работал, нам нужно сначала посмотреть, что происходит, когда весной вызывается save в хранилище, которое использует org.springframework.data.repository.CrudRepository.

Spring пытается определить TransactionAttribute для метода и targetClass.Для метода save и класса CrudRepository короче он не нашел ни одного.Spring использует SimpleJpaRepository в качестве реализации по умолчанию CrudRepository, если он не нашел никаких транзакционных атрибутов в вашем, он будет использовать тот, который указан в SimpleJpaRepository.

@Transactional
public <S extends T> S save(S entity)

Требуется распространение по умолчанию на @Transactional.

Propagation propagation() default Propagation.REQUIRED;

Поддержите текущую транзакцию, создайте новую, если ее не существует.

Как видно из документации выше, если транзакция не указана, она создаст новую.Поэтому, когда вы устанавливаете транзакцию на бизнес-уровне на NOT_SUPPORTED (Выполнение без транзакций), фактический CrudRepository действительно создал свою собственную транзакцию, что означает, что откат не повлияет на нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...