2014-10-11 4 views
2

У меня есть проект EF6, который использует некоторую устаревшую библиотеку (я не могу изменить эту библиотеку). Код, как это в моем проекте:Использовать SqlConnection внутри транзакции Entity Framework

Using scope As New TransactionScope() 
    //Many DAOs calls that work just nice 
    //The call to the legacy library that fails 
End Using 

код, как это в библиотеке:

Using connection As new Sqlconnection("bla") 
    connection.Open() //THIS LINE FAILS INTERMITTENTLY 
    //more code 
End Using 

Я переместил уровень изоляции и объем сделки проекта EF, но я не повезло, все равно. Действительно ли открытие этого соединения происходит вручную внутри транзакции EF?

Исключения, что я получаю:

Операция не действует для государства сделки

или

Связь с основным менеджером транзакций не удалось.

2014-10-11 13: 49: 16,736 ОШИБКА [DataAccess.Services]: Тимбрар: операция недействительна для состояния транзакции. InnerException: Менеджер транзакций MSDTC не смог вытащить транзакцию из диспетчера транзакций источника из-за проблем связи. Возможные причины: существует брандмауэр, и у него нет исключения для процесса MSDTC, обе машины не могут найти друг друга по именам NetBIOS или поддержка сетевых транзакций не включена для одного из двух менеджеров транзакций. (Исключение из HRESULT: 0x8004D02B) 2014-10-11 13: 49: 16767 ОШИБКА [DataAccess.Services]: в System.Transactions.TransactionState.EnlistPromotableSinglePhase (InternalTransaction TX, IPromotableSinglePhaseNotification promotableSinglePhaseNotification, сделка AtomicTransaction) в System.Transactions. Transaction.EnlistPromotableSinglePhase (IPromotableSinglePhaseNotification promotableSinglePhaseNotification) на System.Data.SqlClient.SqlInternalConnection.EnlistNonNull (Transaction ТХ) в System.Data.ProviderBase.DbConnectionInternal.ActivateConnection (транзакция Transaction) на System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConn ectionInternal & соединение) на System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, TaskCompletionSource 1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource 1 повторных попыток, DbConnectionOptions userOptions, DbConnectionInternal & соединение) на System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection (DbConnection outerConnection, DbConnectionFactory ConnectionFactory, TaskCompletionSource 1 retry, DbConnectionOptions userOptions) at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource 1 повторных попыток) на System.Data.SqlClient.SqlConnection.Open() в GuardarBitacora (String sCnn, Int64, String CtePrincipalID NombreArchivos, струнного numUUID, струнного Proveedor, Int32 EstatusOper, струнного MensajeFolio, String MensajeErrorMetodo) в CoreGenWS (String pstrXml, String usuario, String rfc, String password, Boolean sello, Boolean test)на GenArchivoWS (String Новичок, String Ки, String пароль, Byte [] XML, Boolean SELLO, Boolean тест) на Func (String Новичок, String Ки, Int64 pCtePrincipalId, Boolean pftest, Byte [] XML, String pwdFac) в Services.Func (RazonSocial razonSocial, Byte [] xmlValido) на сервисах.(Boolean esBorrador, Int64 usuarioId,, encabezado,, Список 1 detalles, Func 1, Func 3 , Func 1, Func`2)

Я сделал двойную проверку MSDTC службы. Правильно настроен на обоих серверах, и это случается редко, когда система имеет некоторую нагрузку.

+0

«это happends только иногда когда система имеет некоторую нагрузку »Пул соединений предпочитает вернуть вам соединение, которое впервые участвовало в текущей транзакции. Это означает, что часто MSDTC не требуется. Это означает, что только под нагрузкой это может появиться. (Я не знаю причины этой ошибки.) – usr

+0

@usr да и нет. Проблема была полностью связана с MSDTC, но я думаю, что она всегда использовалась, потому что если служба была отключена, эта часть кода всегда терпит неудачу, с большой или низкой нагрузкой. Почему MSDTC прерывался с перерывами? Это большой мистерий. – rsan

+1

Не могу сказать, что ... Я строго держу руки MSDTC. Это действительно нарушитель спокойствия. (И вы знаете, что вы не можете использовать его с Mirroring и AG, правильно? Удачи, разрабатывая план HA.) – usr

ответ

0

Я нашел решение (более или менее). Проблема заключалась в том, что EntityFramework не смог заручиться вторым соединением в одной транзакции и перерос ее в распределенную транзакцию, управляемую службой MSDTC.

Это происходило, потому что даже когда все соединения были сделаны в одной и той же базе данных, некоторые соединения были сделаны с использованием другой строки соединения. Решение использовало ту же строку соединения для всех подключений и установило свойство Application Name в этой строке соединения. После этого я смог отключить службу MSDTC, и приложение может работать без исключений всегда. Даже при большой нагрузке в системе.

Вот спасителем сообщение: http://joeknowsdotnet.wordpress.com/2012/07/19/entity-framework-msdtc-gotchya/

Мое приложение работает propertly и жизнь счастливой, но я до сих пор не знаю, почему при использовании общих транзакций MSDTC не удается иногда ....

Смежные вопросы