@Sergey_USB

Как работает @Transactional? Или что я делаю не правильно?

Добрый день.
реальная задача - есть приложение на клиенте, оно шлет данные на сервер, сервер их пишет в БД, отвечает клиенту или все ОК, данные записаны или ОШИБКА...
Если с БД что-то произошло, она висит, долго не отвечает - то клиенту должно отправиться что произошла ошибка записи.
Одно из условий нормального ответа - быстрая запись в БД.
Клиенту в принципе все равно что произошло с данными, записались они или нет. Он просто в лог у себя пишет что ОК или ОШИБКА.
Данные летят постоянно - потеря одного пакета не страшна.

Я хотел поиграться с зависанием базы и долгим ответом в этой связке.

Для теста сделал следующее -
@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 - значения не имеет, этот вариант остался после последнего теста.

Вопрос - как заставить, при долгом ответе от БД, вернуть ошибку - а не ждать выполнения транзакции?
  • Вопрос задан
  • 119 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы