#batch-processing
#пакетная обработка
Вопрос:
Допустим, в базе данных есть 100 записей для пакетного задания, когда выполняется пакетное задание, выберите эти 100 записей и затем начните обработку. Во время процесса, если ошибка возникает в 10-й записи, я должен откатить все 9 записей, которые уже были обработаны.
Как мы можем спроектировать этот сценарий??? Ваши предложения приветствуются.
Ответ №1:
Я полагаю, что вы спрашиваете, следует ли вам откатывать успешные записи, если ошибка возникает частично во время пакетной обработки.
Вы хотите, чтобы обновления вашей базы данных выполнялись в транзакциях таким образом, чтобы записи базы данных оставались согласованными и законными (в отношении базы данных и бизнес-правил) после фиксации или отката каждой транзакции.
Если каждый элемент в вашем списке из 100 записей может быть обработан и записан по отдельности, то я бы предложил использовать какой-либо флаг (это также может быть поле статуса), чтобы указать, была ли обработана каждая запись, затем просмотрите записи, чтобы обновить каждую из них. Если вы столкнулись с ошибкой, обратите внимание, что где-то (файл журнала, исключение, таблица ошибок… ваш вызов) и двигаться дальше. Когда вы закончите, вы зарегистрируете, какие записи были успешными, а какие неудачными. Затем вы должны иметь возможность вернуться и исправить все, что вызвало проблему (проблемы) в плохих записях, и повторно обработать пропущенные записи.
Если все 100 ваших записей должны завершиться успешно или завершиться неудачей вместе, вам нужно будет включить ваши обновления в транзакцию, чтобы все они завершились успешно или завершились неудачей как одно целое. Это будет работать для десятков записей или (возможно) сотен записей, но попытка масштабирования до тысяч записей в одной транзакции может создать проблемы с масштабируемостью (проблемы производительности и конкуренции), поэтому вам понадобится другое решение для подобного шаблона.
Комментарии:
1. Спасибо за ваш ответ, на самом деле я реализовал только этот способ. Я проверял у других экспертов, как они выполняют такую обработку, и каков наилучший способ сделать это…. Спасибо
Ответ №2:
Возможна различная степень детализации транзакции. Java (JTA) допускает несколько операций записи за один коммит.
- Открытая транзакция
- запись записи
- запись записи
- запись записи
- ошибка
- откат
Большинство баз данных также поддерживают транзакции, которые могут обрабатывать несколько строк или записи.
Это очень распространенное явление.
Комментарии:
1. хорошо ли откатывать все записи, которые были успешными? В вашем примере до точки № 4 все было нормально, и ошибка возникает в точке 5. теперь вы хотите откатить все успешные записи? Как вы думаете, если мы зафиксируем все успешные записи и пометим их выполнением каким-либо флагом, а затем пакетное задание сможет забрать остальные из них (пункт 5 и далее) в следующий раз. Мой вопрос в основном заключается в том, что было бы наилучшим подходом к разработке этого сценария??? Должны ли мы изменить размер пакета, а затем откатить только пакет сбоев или нам следует создать точку сохранения, а затем выполнить откат до точки сохранения???
Ответ №3:
Взгляните на ТОЧКИ СОХРАНЕНИЯ — они в основном разрешают транзакции внутри транзакции. Таким образом, вы можете выполнить довольно много работы, создать точку сохранения и выполнить еще больше работы, только откатившись к последней точке сохранения. Если что-то пойдет не так, вы можете просто откатить всю транзакцию назад.
Комментарии:
1. Изначально я пробовал точки сохранения через Java (у меня нет хранимой процедуры), но моя ситуация этого не позволяет, а также для этого требуется больше кода и логики, чем для сохранения в таблице базы данных со столбцом состояния… Также там была какая-то проблема с производительностью … спасибо за ваше предложение, Майк…