Я создаю механизм для массового вставки (импорта) большого количества новых записей в базу данных ORACLE. Я использую несколько потоков и зависимых операций:Получение исключения «дублирующий идентификатор транзакции» при использовании Transaction.Current.DependentClone
Создание нитей:
const int ThreadCount = 4;
using (TransactionScope transaction = new TransactionScope())
{
List<Thread> threads = new List<Thread>(threadCount);
for (int i = 0; i < ThreadCount; i++)
{
Thread thread = new Thread(WorkerThread);
thread.Start(Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete));
threads.Add(thread);
}
threads.ForEach(thread => thread.Join());
transaction.Complete();
}
Метод, который делает фактическую работу:
private void WorkerThread(object transaction)
{
using (DependentTransaction dTx = (DependentTransaction)transaction)
using (TransactionScope ts = new TransactionScope(dTx))
{
// The actual work, the inserts on the database, are executed here.
}
}
Во время этой операции, я получаю исключение типа System.Data.OracleClient.OracleException
с сообщением ORA-24757: duplicate transaction identifier
.
Что я делаю неправильно? Я неправильно выполняю зависимую транзакцию? Это несовместимо с Oracle? Если да, есть ли рабочий стол?
Пока я apreciate усилия, это не очень помогает. Поскольку соединение не может использоваться несколькими потоками, соединение будет «блокировать» соединение при выполнении его (не) запроса. Это приводит к еще более медленному решению, чем однопоточная среда ... –
Я еще немного подумал о вашем решении. Это будет только ускорять все больше и больше, когда часть «подготовки» (например, импорт, сбор данных и т. Д.) Становится все больше и больше. Не резьбовой INSERT ускорит его, а тот факт, что часть «подготовки» может быть разделена на несколько потоков. После того, как запись «подготовлена» (параллельно), она может быть записана в базу данных, которая станет в вашем случае очередью заблокированных операций INSERT. –