Pregunta

en nuestro proyecto actual, estamos utilizando el Entity Framework de ADO.NET como capa de datos para la aplicación. Hay algunas tareas que requieren ejecutarse en una transacción porque hay mucho trabajo que hacer en la base de datos. Estoy usando un TransactionScope para rodear esas tareas.

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    // Do something...
    transactionScope.Complete();
}

El problema es tan pronto como estoy usando un TransactionScope ocurre una excepción:

  

System.Data.EntityException: el proveedor subyacente falló en Abrir. --- > System.Transactions.TransactionManagerCommunicationException: La comunicación con el administrador de transacciones subyacente ha fallado. --- > System.Runtime.InteropServices.COMException (0x80004005): El error HRESULT E_FAIL se ha devuelto desde una llamada a un componente COM.

Parece que este error tiene que ver con el MSDTC (Microsoft Distributed Transaction Coordinator). Cuando cambio la configuración de seguridad de MSDTC, se produce otra excepción:

  

System.Data.EntityException: el proveedor subyacente falló en Abrir. --- > System.Transactions.TransactionManagerCommunicationException: El acceso a la red para Distributed Transaction Manager (MSDTC) se ha deshabilitado. Habilite el DTC para el acceso a la red en la configuración de seguridad para MSDTC usando la herramienta administrativa de Servicios de componentes.

Sin embargo, MSDTC está configurado, TransactionScope causará un error. ¿Alguien sabe qué va mal aquí?

¿Fue útil?

Solución 8

Hmm, parece funcionar cuando cambio la TransactionScopeOption para " Suprimir " ;:

using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress))
{
    ...
}

¿Todos saben por qué?

Otros consejos

Por defecto, MSDTC tiene el acceso a la red deshabilitado. Para que funcione debe ir a

  

Panel de control- > Administrativo   Herramientas- > Servicios de componentes- > Componentes   Servicios- > Computes- > Mi computadora- > Derecho   haga clic en > Propiedades- > MSDTC- > Seguridad   Configuración

y marque las siguientes casillas de verificación Acceso a DTC de red, Permitir entrada, Permitir salida. La autenticación se debe elegir de acuerdo con su entorno. Es posible que también desee consultar DTCPing herramienta para depurar transacciones distribuidas. Para darle un acceso directo, es posible que necesite modificar su registro:

  

HKLM \ Software \ Policies \ Microsoft \ Windows   NT \ RPCRestrictRemoteClients = 0   HKLM \ Software \ Policies \ Microsoft \ Windows NT \ RPCEnableAuthEpResolution = 1

para poner todo en marcha.

Sí, funciona con Supress, porque le está diciendo que suprima o ignore la transacción ambiental y cree una nueva transacción local. Como la transacción es local, no es una transacción distribuida, por lo que no usa MSDTC, pero probablemente no debería usar Suprimir y debería usar Requerido en su lugar.

Esto significa que está suprimiendo cualquier Transacción que pueda estar vigente actualmente cuando ingresa su bloque de código, por lo que cualquier actualización que realice su código no se revertirá si el " ambiente " exterior " La transacción decide revertir.

Este es el artículo que usamos para resolver nuestro propio problema similar:

Solución de problemas con MSDTC

Esto es básicamente un addendum a la respuesta de Nikolay R . Él ya cubrió algunas de las sugerencias enumeradas en el artículo.

Nota: el artículo es parte de la documentación de Biztalk, pero puede aplicarse a cualquier cosa que use MSDTC.

" Si está utilizando Entity Framework con transacciones, Entity Framework abre y cierra automáticamente una conexión con cada llamada a la base de datos. Por lo tanto, cuando utiliza transacciones, está intentando distribuir una transacción a través de múltiples conexiones. Esto se eleva a MSDTC. & Quot;

Puede pasar el contexto de su base de datos a la clase o función de la persona llamada en su transacción.

Tal vez esta sea su respuesta: Error de MSSQL 'El proveedor subyacente falló en Open'

Suprimir la transacción es útil si desea ejecutar algún código que podría fallar, pero no desea cancelar la transacción debido a que falla.

La pregunta que debes hacerte es la siguiente: ¿Está accediendo a más de 1 recurso duradero en su transactionScope? Quiero decir, ¿abres conexiones a más de 1 DB?

Esta es una pregunta importante ya que la transacción se escalará hacia DTC si accede a más de 1 recurso duradero.

Al menos dos recursos duraderos que admiten notificaciones de una sola fase se incluyen en la transacción. Por ejemplo, al alistar una sola conexión con no se promueve una transacción. Sin embargo, cada vez que abre una segunda conexión a una base de datos que hace que la base de datos se enliste, la infraestructura de Transacciones del Sistema detecta que es el segundo recurso duradero en la transacción y la eleva a una transacción de MSDTC. Fuente: MSDN

Si ese es el caso, puede resolver su problema anidando suscopios de transacciones correctamente, por ejemplo:

//Create rootScope
using(TransactionScope rootScope = new TransactionScope()) 
{ 
    using(TransactionScope scope2 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB1
         ...

         //Complete this ambient transaction
         scope2.Complete();
    } 

    using(TransactionScope scope3 = new 
    TransactionScope(TransactionScopeOption.Required)) 
    {
         //Do work on DB2
         ...

         //Complete this ambient transaction
         scope3.Complete();
    } 

    //Complete rootScope
    //The whole transaction will only be committed if you call 
    //Complete on the rootScope
    rootScope.Complete();

}

Puede encontrar más información sobre TransactionScopes, cómo funciona el anidamiento, ... en MSDN .

Espero que esta respuesta pueda ayudar a las personas en el futuro.

Si el servicio Coordinador de transacciones distribuidas no se inicia, Entity Framework no puede conectarse a la base de datos. Abra e inicie el Coordinador de transacciones distribuidas

Servicios - > Coordinador de transacciones distribuidas

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top