#parallel-processing #transactions #kentico
#параллельная обработка #транзакции #kentico
Вопрос:
Я выполняю импорт данных, завернутых в CMSTransactionScope
.
Какой был бы наиболее эффективным и практичным способом параллельного импорта данных и отката при возникновении ошибок? Проблема, которую я вижу, заключается в том, что, поскольку она параллельна, я не знаю, могу ли я включить вставленные объекты в транзакцию, если они отделены от нового потока.
Есть ли какой-либо способ сделать это или это следует обрабатывать по-другому?
Ответ №1:
Если вы выполняете код параллельно, чтобы добиться более высокой производительности, и вы в основном вставляете строки одну за другой, то маловероятно, что он будет работать лучше, чем при выполнении в одном потоке. В этом случае я бы рекомендовал использовать один поток в сочетании с CMSTransactionScope
, и потенциально ConnectionHelper.BulkInsert
.
В любом случае, если вы все еще хотите выполнять свои запросы параллельно, вам нужно реализовать какой-то вид синхронизации (например, блокировку), чтобы гарантировать, что все инструкции выполняются до того, как попадет код CMSTransactionScope.Commit()
(это в основном означает потерю производительности). В противном случае запросы выполнялись бы в отдельных транзакциях. Более того, вы должны убедиться, что CMSTransactionScope
объект всегда создается с одним и тем же экземпляром IDataConnection
(это должно происходить по умолчанию, когда вы не передаете соединение конструктору).
Второй подход кажется мне подверженным ошибкам, и я бы предпочел взглянуть на различные способы оптимизации кода (использование асинхронности и т.д.)
Комментарии:
1. Я определенно могу понять и согласиться с вами в отношении первого подхода к вставке данных. Как насчет обновления данных? Например, имея transactionscope, а затем параллельно обновляя строки одну за другой? Мне интересно, возможно ли это? Или запрос обновления kentico sql просто приведет к взаимоблокировке, потому что каждый поток имеет новую область подключения? Возможно, я слишком много думаю об этом..
2. Если вы выполняете, например, a
Parallel.ForEach()
внутри aCMSTransactionScope
, я считаю, что это должно работать без каких-либо взаимоблокировок. Область транзакции использует свою собственную область подключения, которая, я надеюсь, будет использоваться повторно даже при использовании нескольких потоков. Однако я думаю, что прирост производительности будет минимальным, если вообще будет. Лучший способ выяснить это — пойти дальше и попробовать 🙂