Откат транзакции при сбое метода @Async - PullRequest
0 голосов
/ 14 февраля 2019

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

Я столкнулся с проблемой, когда пользователь может выбрать либо выбрать вручную, либомашина без водителя например.Так что, если он выберет без водителя, то ручная конфигурация будет отключена и наоборот.Учтите, что он переходит из режима без драйверов в режим ручного управления, конфигурация без драйверов отключена, и я звоню в другую службу, чтобы отключить ручную настройку (которая происходит при асинхронном вызове).Я добавил @Async по причине, поскольку это требует много времени.

пример

// Caller
@Override
public void enableDriverlessDriving(DriverlessDriving driverlessConfig) {

     validator.validate(driverlessConfig);

     driverlessDao.update(driverlessConfig);

     if(drivelessConfig.isEnabled()) {

           manualService.onDrivelessEnabled(driverlessConfig.getUserId());
     }
}

// Callee
@Override
@Aysnc
public void onDrivelessEnabled(int userId) {

 .....
   // retrofit rest call. Timeout for 30 secs
   ManualConfig config = client.getManualConfiguration(userid,30);

   config.isEnabled(false);

   try {
         // retrofit rest call. timeout for 30 secs
         client.updateManualConfig(config, userId,30);
   }catch(CheckedExceptions e) { // throwing checked exceptions here.
      LOGGER.error(...)
      return;
   }

}

Если при вызове покоя возникает ошибка вызова для отключения ручной настройки, конфигурация без драйвероввключен, но ручная настройка не выключена, оба включены.

Вопрос:

  1. Добавление @Transactional в метод вызова и вызываемого абонента работает?- Может быть, но тогда это повлияет на производительность, в этом случае не будет использоваться @Async.

  2. Если метод вызывающей стороны имеет @Transactional, но @Asyncметод должен иметь @Transactional(REQUIRES_NEW)?Будет ли откат по методу вызывающего абонента @Transaction откатить транзакцию для проверенного исключения в методе вызываемого абонента?

Я ожидаю решения, в котором я добиваюсь целостности данных без ущерба для производительности (яхочу @Async работать так, как сейчас работает)

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я не буду предлагать объединить @Async и @Transactional, чтобы я мог запустить службу любым способом.Я просто создаю асинхронную оболочку вокруг службы и использую ее вместо этого, если необходимо.

@ Транзакционный с @ Async

, когда @Transactional Spring @Component вызываетметод с аннотацией @Async этого не происходит.Вызов асинхронного метода планируется и выполняется позднее исполнителем задачи и, таким образом, обрабатывается как «свежий» вызов, то есть без транзакционного контекста.Если метод @Async (или @Component, в котором он объявлен) сам по себе не является @Transactional, Spring не будет управлять какими-либо необходимыми транзакциями.

Если аннотация @Async используется с особой осторожностьюдолжен приниматься в отношении транзакций. В этом случае транзакция распространяется через иерархию вызовов от одного Spring @Component к другому.

Чтобы Spring мог управлять транзакцией метода @Async либо@Component или сам метод должен объявлять аннотацию @Transactional, таким образом Spring будет управлять транзакцией, даже если метод выполняется асинхронно.

0 голосов
/ 14 февраля 2019

Это отличный вопрос, я сталкивался с этим некоторое время назад.

  1. Нет, добавление @Transactional не будет работать, потому что при запуске метода @Async он работает нановый поток
  2. Я думаю, что нет способа сделать откат на основе вызова метода @Async.
  3. Откат можно заставить работать без асинхронных вызовов, я не знаю, зачем вам это нужновызвать метод без драйвера как @Async, но если вы удалите его, он будет работать.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...