Я просто добавлю, что update_recordset (точнее говоря - update в SQL Server) вешает блокировки не только на те записи, которые он реально обновляет, но и на те записи, которые попали в выборку по индексу. Ну то есть - если у нас подходящего индекса нету, то SQL может попробовать поискать по какому-то случайному индексу по dataAreaId, а перед поиском - попробуем все это ненадолго заблокировать. Плюс - иногда SQL Server переглючивает или индексы фрагментируются или еще что-то подобное случается, и оно выбирает план исполнения по не тому индексу. В этом случае тоже случаются аналогичные блокировки.
В то же время, если нам надо обновить не 100-200, а эдак 100K-200K записей, то особой альтернативы update_recordset просто нету. Да - есть вероятность блокировок. Да - надо строить правильные индексы. Да надо регулярно их перестраивать и строить статистику. Да -есть вероятность время от времени нарваться на блокировки. Но просто в каждом конкретном случае мы должны сравнивать риски больших задержек из за пошагового обновления и риски задержек из за взаимных блокировок.
Плюс - я не уверен что во всех сценариях мы можем создавать отдельную транзакцию на каждое обновление. При этом если у нас одна большая транзация и обновление идет по одной записи в while select forupdate, то порядок обновления в разных кусках кода вполне может быть разным. (К слову сказать - в исходном примере вообще в while select не стоит order by, соответственно порядок обновления записей не является гарантированым...)
Последний раз редактировалось fed; 31.01.2019 в 12:53.
|