Добрый день.
реальная задача - есть приложение на клиенте, оно шлет данные на сервер, сервер их пишет в БД, отвечает клиенту или все ОК, данные записаны или ОШИБКА...
Если с БД что-то произошло, она висит, долго не отвечает - то клиенту должно отправиться что произошла ошибка записи.
Одно из условий нормального ответа - быстрая запись в БД.
Клиенту в принципе все равно что произошло с данными, записались они или нет. Он просто в лог у себя пишет что ОК или ОШИБКА.
Данные летят постоянно - потеря одного пакета не страшна.
Я хотел поиграться с зависанием базы и долгим ответом в этой связке.
Для теста сделал следующее -
@Transactional(timeout = 20)
public void generate() {
for (int i = 0; i < 200; i++) {
List<TagEntity> list = new ArrayList<>();
for (int j = 0; j < 50_000; j++) {
int random_number = (int) (Math.random() * 10);
TagEntity tagEntity = new TagEntity();
tagEntity.setTag("Tag_" + random_number);
list.add(tagEntity);
}
tagRepository.saveAll(list);
}
}
Это сервис - пишет в репозиторий tagRepository.
Этот метод вызывается из контроллера.
Создаем пакет из 50тыс сущностей TagEntity (только два поля - ID и Tag (стринг))
и пишем в БД, и так 200 раз.
В таком виде этот метод падает на втором или третьем круге с нужной ошибкой - время транзакции превышено.
Но если изменить этот код - вот так:
public void generate() {
for (int i = 0; i < 200; i++) {
List<TagEntity> list = new ArrayList<>();
for (int j = 0; j < 50_000; j++) {
int random_number = (int) (Math.random() * 10);
TagEntity tagEntity = new TagEntity();
tagEntity.setTag("Tag_" + random_number);
list.add(tagEntity);
}
saveList(list);
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 6)
public void saveList(List<TagEntity> list) {
tagRepository.saveAll(list);
}
то он будет работать пока не выполниться весь.
даже если БД подвесить надолго, если запустить несколько экземпляров записи, короче что не делать - он не падает по timeout никак.
propagation - значения не имеет, этот вариант остался после последнего теста.
Вопрос - как заставить, при долгом ответе от БД, вернуть ошибку - а не ждать выполнения транзакции?