Ошибка - транзакция, связанная с текущим соединением, завершена, но не была удалена
У меня возникли проблемы с использованием TransactionScope
для переноса нескольких запросов к базе данных в транзакцию. Я использую SqlBulkCopy с batchsize 500. Когда я увеличил размер партии до 1000, я получаю сообщение об ошибке:
Завершена транзакция, связанная с текущим соединением но не был ликвидирован. Сделка должна быть удалена до соединение может использоваться для выполнения операторов SQL.
Это код, который я использую:
using (var scope = new TransactionScope())
{
using (var connection = (SqlConnection)customerTable.OpenConnection())
{
var table1BulkCopy = new SqlBulkCopy(connection)
{
BatchSize = BATCH_SIZE,
DestinationTableName = TableName1
};
table1BulkCopy.WriteToServer(table1DataTable);
var table2BulkCopy = new SqlBulkCopy(connection)
{
BatchSize = BATCH_SIZE,
DestinationTableName = TableName2
};
table2BulkCopy.WriteToServer(table2DataTable);
var table3BulkCopy = new SqlBulkCopy(connection)
{
BatchSize = BATCH_SIZE,
DestinationTableName = TableName3
};
table1BulkCopy.WriteToServer(table3DataTable);
var table4BulkCopy = new SqlBulkCopy(connection)
{
BatchSize = BATCH_SIZE,
DestinationTableName = TableName4
};
table4BulkCopy.WriteToServer(table4DataTable);
scope.Complete();
}
}
Ответы
Ответ 1
Я знаю, что это поздно, но, возможно, это поможет кому-то другому.
Это может произойти, когда транзакция истечет. Вы можете увеличить таймаут для своей транзакции, как это (используйте значения, соответствующие ожидаемой длине вашей транзакции). Код ниже в течение 15 минут:
using (TransactionScope scope =
new TransactionScope(TransactionScopeOption.Required,
new System.TimeSpan(0, 15, 0)))
{
// working code here
}
Вот почему он мог работать в batchsize 500, а не на 1000.
Ответ 2
Я обнаружил, что установка тайм-аута в TransactionScope не работает для меня. Мне также нужно было добавить следующий ключ конфигурации в конец тега machine.config <configuration>
, чтобы пропустить максимальный тайм-аут по умолчанию в течение 10 минут.
<system.transactions>
<machineSettings maxTimeout="00:30:00" /> <!-- 30 minutes -->
</system.transactions>
Кредит:
http://thecodesaysitall.blogspot.com.au/2012/04/long-running-systemtransactions.html
Ответ 3
Переместите scope.Complete();
вне блока connection
.
using (var scope = new TransactionScope())
{
using (var connection = (SqlConnection)customerTable.OpenConnection())
{
//
}
scope.Complete();
}