Мне не удалось найти ничего похожего на то, что я делаю, и из-за проблем с бюджетом я вынужден обратиться к вам всем за помощью. В настоящее время я пишу приложение для импорта, которое может импортировать переменное количество записей. Скорее всего, это переменное число будет очень высоким, потенциально в миллионах. Мы используем потоковую передачу WCF для отправки фрагментов данных на сервер для обработки. На стороне сервера мы помещаем данные в временную таблицу SQL для проверки. Оттуда, используя TPL для извлечения заданного количества записей, а затем вставьте их в постоянное хранилище SQL-хранилища. Там гораздо больше, но в двух словах это основная часть. В настоящее время единственной нерешенной проблемой является то, что мы разрешаем пользователю отменять импорт в любое время. Это означает, что отмена может произойти во время сохранения этих записей. Нам нужно иметь возможность откатить все вставленные / обновленные записи. Поскольку мы используем TPL для обработки записей, мне крайне сложно делиться транзакциями. Я использую подход DependentTransaction, описанный в MSDN (очень похоже, http://msdn.microsoft.com/en-us/library/system.transactions.dependenttransaction(v=VS.100).aspx). Вот некоторые фрагменты кода:
var currentTransaction = System.Transactions.Transaction.Current;
...
// DataTable is simply a placeholder for X amount of records from the SQL temp table
var partitions = Partitioner.Create(0, DataTable.Rows.Count, 100);
Parallel.ForEach(partitions, (partition, state) =>
{
using (var parallelTransaction = new TransactionScope(currentTransaction.DependentClone((DependentCloneOption.RollbackIfNotComplete)))
Внутри этой итерации TPL происходит много операций выбора, вставки и обновления. Я хочу, чтобы все это происходило в рамках одной транзакции, если это возможно. Или, по крайней мере, быть управляемым TransactionScope, чтобы мы могли откатить все назад. Я получаю сообщение об ошибке, что «контекст транзакции уже используется», а затем он прерывается, почти мгновенно.
Правильно ли я использую DependentTransaction? Может ли моя просьба быть возможной? Я знаю, что транзакции, как правило, являются последовательными и не используются в этом контексте, но для простоты и для того, чтобы избавить нас от необходимости реализовывать некоторые сумасшедшие функции для отслеживания вставленных записей и отката вручную, транзакция была бы идеальной!
Есть предложения?
ПРИМЕЧАНИЕ. Я пытался использовать подход локального состояния к параллельной итерации, но независимо от того, что я делаю, все это генерирует одно и то же исключение. Кроме того, использование RollbackIfNotComplete или BlockCommitUntilComplete не имеет никакого отношения.