Откат транзакции не происходит при возникновении ошибки во вложенном методе - PullRequest
0 голосов
/ 03 апреля 2019

В моем недавнем проекте я столкнулся со сценарием, в котором мне нужно откатить работу базы данных при возникновении ошибки во вложенном методе. Ранее я работал с @Transactional по одному методу. В то время все работало нормально. Но в текущем сценарии у меня есть зависимость от другого метода. Поэтому мне нужно откатить, когда ошибка происходит вложенным методом. Я хочу откат по этому методу

@Transactional
@Override
public String updateCustomOfficeHour(OfficeHour officeHour) {
    if (officeHour.getId() == null || officeHourRepository.getFirstById(officeHour.getId()) == null)
        throw new EntityNotFoundException("No Office-Hour found with this id");

    OfficeHour temp = officeHourRepository.getFirstById(officeHour.getId());
    List<OfficeHour> officeHours = officeHourRepository.findByFromDateAndToDate(temp.getFromDate(), temp.getToDate());

    List<OfficeHour> tempList = new ArrayList<>();
    for (OfficeHour officeHourObj : officeHours) {
        officeHourObj.setDeleted(true);
        tempList.add(officeHourObj);
    }
    officeHourRepository.saveAll(tempList);
    this.createCustomOfficeHour(officeHour);
    return "Updated Custom-Office-Hour";
}

Здесь у меня есть операция с базой данных в строке officeHourRepository.saveAll(tempList); Мне нужно откатиться при возникновении ошибки в методе this.createCustomOfficeHour(officeHour);. Этот метод

   @Transactional
    @Override
    public String createCustomOfficeHour(OfficeHour officeHour) {
        if (officeHour.getFromDate() == null || officeHour.getToDate() == null
                || officeHour.getFirstOutTime() == null || officeHour.getLastInTime() == null
                || officeHour.getInTime() == null || officeHour.getOutTime() == null)
            throw new EntityNotFoundException("Null value received for OfficeHour fields!");

        if (officeHour.getToDate().compareTo(officeHour.getFromDate()) < 0)
            throw new EntityNotFoundException("FromDate is Getter than ToDate");

        if (officeHourRepository.isFromDateExist(officeHour.getFromDate()).longValue() > 0
                || officeHourRepository.isToDateExist(officeHour.getToDate()).longValue() > 0) {
            throw new EntityNotFoundException("FromDate/ToDate is already assigned");
        }

        if (officeHourRepository.isDateExistsBetweenFromAndToDate(officeHour.getFromDate(), officeHour.getToDate()).longValue() > 0)
            throw new EntityNotFoundException("Office Hour Already Assigned In This Range");


        for (int i = 1; i <= count; i++) {
           ........
           ........
           ........
           officeHourRepository.save(obj);

        }
        return "Custom Office-Hour Created";
    }

А это мой Exception класс

public class EntityNotFoundException extends RuntimeException {

    public EntityNotFoundException(String message) {
        super(message);
    }
}

Я также добавил spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect в application.properties

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 03 апреля 2019

Ваш EntityNotFoundException является непроверенным исключением и следует за пружинными документами :

Поведение по умолчанию для декларативного управления транзакциями в соответствии с соглашением EJB (откат выполняется только автоматическидля непроверенных исключений)

транзакция должна быть откатана по умолчанию.

Это потому, что updateCustomOfficeHour и createCustomOfficeHour обрабатываются в одной транзакции (переопределение распространения отсутствует)вот так используется значение REQUIRED по умолчанию).

Вы можете добавить явный откат для своего исключения для метода updateCustomOfficeHour, но он все равно должен быть избыточным:

@Transactional(rollbackFor = {EntityNotFoundException.class})
...