Часто решением проблем на пути к оптимизации кода (а именно увеличению скорости выполнения задач) может быть работа с транзакциями.
Сегодня я хочу предложить решение вопроса при обращении к базе данных в цикле.
У нас будет слой сервиса, не будем нарушать принципы дизайна приложений:
И естественно наш репозиторий:
Ну и вот настало время нашего первого примера. Пример кода будет состоять в том, что мы создаем N количество пользователей и сохраняем их в базе данных. Для простоты примера мы и создание и сохранение будем производить в одном цикле. Вот он пример:
Переходим ко второму случаю. Как вы уже наверное догадались мы будем совершать полностью весь цикл в одной транзакции. Вот пример кода:
Вернемся к нашим циклам и и сравним наши два ранее рассмотренных случая. Тестирование я проводил на своем ноутбуке, каждое значение получал как среднее трех попыток. На другой машине цифры будут отличаться, но динамика будет та же. Производил замеры при создании 10, 20, 30, 40 и 50 тысяч пользователей и соответственно замерял время. Под цифрой 1 – в раздельной транзакции, под цифрой 2 в одной транзакции весь цикл.
Разница впечатляющая на мой взгляд. Для более наглядной разницы не поленился создать график.
Мы разобрали два кейса, которые являются в некотором роде противоположностями. Где у одного плюс, у другого минус и наоборот. А может все-таки можно как то подумать и объединить не объединяемое и взять по максимуму от обоих вариантов. И мой ответ «ДА». Но прежде чем его показать, давайте приведем наш код к лучшей читаемости, чтобы дядюшке Бобу было приятно (Роберт Мартин «Чистый код») и вынесем логику внутри цикла в отдельный метод:
Теперь же пробуем объединить первый и второй кейс: