У меня есть стандартная программа, которая использует рекурсивный цикл для вставки объектов в базу данных SQL Server 2005 первый вызов, который инициирует цикл, включается в рамках использования транзакции TransactionScope. Когда я сначала называю ProcessItem, myItem данные вставляются в базу данных как ожидалось. Однако, когда ProcessItem называют или от ProcessItemLinks или от ProcessItemComments, я получаю следующую ошибку.
“Операция не допустима для состояния транзакции”
Я выполняю это в отладке с VS 2008 в Windows 7 и имею MSDTC, работающий для включения распределенных транзакций. Код ниже не является моим производственным кодом, но изложен точно то же. AddItemToDatabase является методом на классе, я не могу изменить и использую стандартный ExecuteNonQuery (), который создает соединение, затем закрывает и располагает когда-то завершенный.
Я посмотрел на другую регистрацию на здесь и Интернет и все еще не могу решить этот вопрос. Любая справка очень ценилась бы.
using (TransactionScope processItem = new TransactionScope())
{
foreach (Item myItem in itemsList)
{
ProcessItem(myItem);
}
processItem.Complete();
}
private void ProcessItem(Item myItem)
{
AddItemToDatabase(myItem);
ProcessItemLinks(myItem);
ProcessItemComments(myItem);
}
private void ProcessItemLinks(Item myItem)
{
foreach (Item link in myItem.Links)
{
ProcessItem(link);
}
}
private void ProcessItemComments(Item myItem)
{
foreach (Item comment in myItem.Comments)
{
ProcessItem(comment);
}
}
Вот верхняя часть отслеживания стека. К сожалению, я не могу показать сборке до этой точки как ее уязвимая информация компании, которую я не могу раскрыть.
at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalTransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, Transaction atomicTransaction)
at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSinglePhaseNotification promotableSinglePhaseNotification)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
Распределенные транзакции преждевременно поседели:)
Обычные подозреваемые
Проверьте, нормально ли работает MSDTC, используя такие инструменты, как dtcping
Также проверьте, вставив небольшой количество элементов вначале. Кажется, что ваш код находится в рекурсивном цикле, который может обрабатывать большой объем данных. Возможно, вы выполняете много запросов, и время транзакции истекает.
Иногда в System.Transactions.Transaction.Current есть некоторые подсказки о том, что произошло. Добавьте наблюдение за этой глобальной переменной