У меня есть процедура, которая использует рекурсивный цикл для вставки элементов в базу данных 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()