Часть сделки не совершена - PullRequest
1 голос
/ 11 ноября 2019

У меня есть вопрос об использовании @Transactional в приложении Spring Boot. Недавно я столкнулся с очень странной ошибкой, которую трудно воспроизвести и отладить (произошла только один раз, но она довольно серьезна).

У меня есть планировщик, выполняющий несколько действий (вызов внешних служб). Эти службы обычно имеют @Transactional в своих открытых методах и вызывают другие службы, обновляют данные и т. Д. Это выглядит следующим образом:

@Service
@AllArgsConstructor
public class Scheduler {

  private final EntityService service;

  @Scheduled(...)
  public void runTasks() {
    service.performUpdates();
  }

}

@Service
@AllArgsConstructor
public class EntityService {

  private final OtherService otherService;
  private final EntityRepo repo;

  @Transactional
  public void performUpdates() {
    Entity entity = loadEntity(1);
    entity.setValue(entity.getValue() + 1); // THIS WAS NOT COMMITED, VALUE STAYED UNCHANGED
    otherService.someTask() // THIS WAS INVOKED CORRECTLY
  }

  public void loadEntity(int id) {
    return repo.getEntity(int id)
 }

Обновление сущности (которое обычно работает нормально) не было зафиксировано в этот рази стоимость осталась неизменной в конце транзакции. Другой метод был вызван правильно.

Итак, мой вопрос, неправильно ли я использую транзакцию? Что может произойти, чтобы вызвать такую ​​загадочную ошибку?

РЕДАКТИРОВАТЬ: полный код

public class ClanService {
    private final ClanRepository clanRepository;
    private final QuestService questService;

    @Transactional
    @Override
    public void performTurnUpdates(int turnId) {
        for (Clan clan : getAllClans()) {
            ...
            checkLevel(turnId, clan);
            ...
        }
    }

    private void checkLevel(int turnId, Clan clan) {
        if (clan.getInformation() >= clan.getNextLevelInformation()) {

            // DID NOT UPDATE
            clan.changeInformation(- clan.getNextLevelInformation());
            clan.setInformationLevel(clan.getInformationLevel() + 1);

            // assign quests
            // DID UPDATE
            questService.assignQuests(clan, notification);
        }
      }
   }

  @Override
  public List<Clan> getAllClans() {
    return clanRepository.findAll();
  }
}

Этот метод performTurnUpdates был вызван из-за пределов этой службы.

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