Синхронизация транзакций должна быть оставлена серверу базы данных и не управляться на уровне приложения.С точки зрения сервера базы данных, независимо от того, сколько у вас JVM (потоков), это параллельные клиенты базы данных, запрашивающие операции чтения / записи.Вам не следует беспокоиться о таких проблемах.
Что вам следует сделать, так это постараться максимально уменьшить конфликт при разработке вашего решения, например, с помощью (удаленного) метода разбиения.
, если я запускаю несколько экземпляров моего пакетного задания (несколько JVM), существует высокая вероятность того, что оба экземпляра могут быть получены одним и тем же набором записей, даже если я использую «оптимистический»или «пессимистическая блокировка» или «выбрать для обновления», так как мы не можем заблокировать записи во время выбора
Разделение данных по проекту устранит все эти проблемы.Если вы предоставляете каждому экземпляру набор данных для работы, нет никаких шансов, что работник выберет одну и ту же из записей другого работника.Майкл привел подробный пример в этом ответе: https://stackoverflow.com/a/54889092/5019386.
(логическое) Однако разбиение на разделы не решит проблему конфликта, поскольку все работники будут читать / записывать из / в одну и ту же таблицу, ноэто характер проблемы, которую вы пытаетесь решить.Я хочу сказать, что вам не нужно начинать блокировать / разблокировать таблицу в вашем дизайне, оставьте это для базы данных.Некоторые серверы баз данных, такие как Oracle, могут записывать данные одной и той же таблицы в разные разделы на диске для оптимизации одновременного доступа (что может помочь при использовании разбиения), но опять же это бизнес Oracle, а не Spring (или любой другой фреймворк).
Не каждый может позволить себе Oracle, поэтому я бы искал решение на концептуальном уровне.Я успешно использовал следующее решение (физическое разбиение "Pseudo") для решения проблемы, подобной вашей:
- Шаг 1 (в последовательном режиме): копировать / разбивать необработанные данные во временные таблицы (в последовательном)
- Шаг 2 (параллельно): запустить несколько рабочих над этими таблицами вместо исходной таблицы с миллионами строк.
- Шаг 3 (последовательно): скопировать / обновить обработанные данные обратно в исходныйтаблица
Шаг 2 устраняет проблему конфликта.Обычно стоимость (Шаг 1 + Шаг 3) пренебрежимо мала по сравнению с Шагом 2 (еще более пренебрежима, если Шаг 2 выполняется последовательно).Это хорошо работает, если обработка является узким местом.
Надеюсь, это поможет.