#java #mysql #hibernate #spring-boot #transactional
#java #mysql #переход в спящий режим #весенняя загрузка #транзакционный
Вопрос:
В моем недавнем проекте я столкнулся со сценарием, когда мне нужно откатить работу базы данных при возникновении ошибки во вложенном методе. Ранее я работал с @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:
Ваше EntityNotFoundException
исключение не проверяется и соответствует документам spring:
Поведение Spring по умолчанию для декларативного управления транзакциями соответствует соглашению EJB (откат выполняется автоматически только для непроверенных исключений)
транзакция должна быть откатана по умолчанию.
Это связано с тем, что updateCustomOfficeHour
и createCustomOfficeHour
обрабатываются в рамках одной транзакции (здесь нет переопределения распространения, поэтому используется значение по умолчанию REQUIRED).
Вы могли бы добавить явный откат для вашего исключения в updateCustomOfficeHour
методе, но это в любом случае должно быть избыточным:
@Transactional(rollbackFor = {EntityNotFoundException.class})
Комментарии:
1. Я добавил
@Transactional(rollbackFor = {EntityNotFoundException.class})
наupdateCustomOfficeHour
, но получаю красное предупреждение дляrollbackFor
. Это показываетCannot resolve method 'rollbackFor'
. Что мне теперь делать?2. Если вы используете,
org.springframework.transaction.annotation.Transactional
должно бытьrollbackFor
@AvijitBarua3. @ShafinMahmud я получил
rollBackOn
, но это не сработало.4. Попробуйте установить @Transactional(распространение = Propagation. ОБЯЗАТЕЛЬНО) во внутреннем методе.
5. @MaciejKowalski Я установил
@Transactional(propagation = Propagation.REQUIRED)
вклcreateCustomOfficeHour
и установил@Transactional(rollbackFor = {EntityNotFoundException.class})
вклupdateCustomOfficeHour
. Но, к сожалению, не получил ожидаемого результата.