Buscando al culpable

Os pongo en antecedentes Sql Azure no soporta transacciones distribuidas y para confirmarlo podéis leer esta entrada TransactionScope() in Sql Azure, o por lo menos con ese mismo escenario es con el que yo me he encontrado.

La aplicación está desarrollada utilizando los siguientes componentes.

  • Aplicación desarrollada en MVC3
  • Entity Framework 4.2
  • Sql Azure

Una de las reglas de negocio de esta aplicación es que a la entidad cliente se le debe de asociar un usuario, pues bueno que fue lo que hice, para no reinventar la rueda y puesto que MVC3 me dota de la posibilidad de utilizar MemberShip Provider.

Vamos a utilizar el metodo MemberShip.CreateUser y en la entidad Cliente creo una columna que sea un Guid y que haga referencia a este, aparentemente solucionado en un entorno de desarrollo, pero cuando hago el despliegue en Azure me encuentro con un magnífico error, que resumiendo me esta confirmando que este no soporta transacciones distribuidas.

Nos queda localizar quien es el culpable de este error y nos ponemos manos a la obra.

1. Transaction Scope. Primer descartado puesto que en otros puntos de la aplicación se está utilizando y no generaba ningún error.

2. MemberShip Provider. Para que TransactionScope cree una transacción distribuida una de las condiciones es que la cadena de conexión sea diferente. Así que vamos a confirmar que MemberShip no altera la cadena de conexión. Donde miramos? Pues en la propiedad  Provider del objeto MemberShip y dentro de este en el campo privado _sqlConnectionString.

Esto lo podemos hacer de dos formas para el más friki con System.Reflection utilizando este código.

   1: var connectionStringField = Membership.Provider.GetType()

   2: .GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);

   3:  

   4: var conexion = connectionStringField.GetValue(Membership.Provider);

Y para los que no tienen ganas de complicarse la vida que utilicen “inspección rapida” de visual studio o cualquier otro mecanismo yo utilizo este puesto que es rápidoSonrisa Shift+F9, bueno eso lo dejo a elección del consumidor.

Dibujo3

Pues me parece que solo nos queda un candidato, será será EntityFramework, pues sí hemos acertado y por qué?.

3. EntityFramework. A partir de la versión 4.2 hace cosas por nosotros, que no se si las deberían de hacer pero sin preguntarlo agregan a nuestra cadena de conexión “Application Name=EntityFrameworkMUE” si esta en nuestro config no contiene “Application Name”. Y de verdad que no miento y para ello lo mejor es abrir con Reflector EntityFramework.dll y en el objeto InternalConnection localizamos un metodo estático que se llama.

“AddAppNameCookieToConnectionString”

No muestro el código completo pero si un aperitivo de lo que haceSonrisa

   1: builder.ApplicationName = "EntityFrameworkMUE";

   2: connection.ConnectionString = builder.ToString();

   3: return connection.ConnectionString;

Redoble de tambores. a partir de la versión 4.2 EntityFramework es el causante de generar transacciones distribuidas, puesto que agrega a la cadena de conexión cosas sin nuestro permiso.

En esta otra entrada del foro de c# podéis encontrar opiniones de otras personas con las que coincido en su totalidad Transaction Scope y sobre todo lo que más me alegra es que en ese foro se muestre la solución a una respuesta que en otro con muchísimo prestigio se encuentre esto Using TransactionScope with Entity Framework code first and universal providers, no somos tan malos. Así que a participar, que entre todos podemos hacer que la cosa mejore

Solución.

Agregar a nuestra cadena de conexion en el config “Application Name=No me ayudes tanto que me gusta hacerlo a mi”

Conclusiones.

Sencillas.

1. Que MVC no debería incorporar MemberShip y mucho menos crear un Controlador AcountController con todo el mecanismo incorporado. Uno es abierto y fácil de configurar “MVC” y el otro es hermético como una lata, MemberShip. Por algo se creo en 2005.

2.Que le agradezco a EntityFramework todo lo que me ahorra, pero que no haga cosas de este tipo,  que tenga yo la libertad de configurar lo que quiera y como quiera. A los señores del equipo yo les invitaría a tomarse unas vacaciones en conjunto con el equipo de MVC.

3. Que estamos en un momento en el que los cambios tan rápidos nos están haciendo caer en este tipo de cosas, detalles que son muy difíciles de resolver y que por tanto, con un poco más de calma quizá todos seamos más felices, quien produce y quien consume.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *