transacciones salida procedimientos procedimiento parametros error ejemplos ejemplo anidadas almacenados almacenado sql-server entity-framework transactions

sql server - salida - EF6 ajusta cada llamada a un procedimiento almacenado en su propia transacción. ¿Cómo prevenir esto?



transacciones en sql server pdf (4)

Perfilado con el Analizador de SQL Server: EF 6 ajusta cada llamada de procedimiento almacenado con BEGIN TRAN y COMMIT TRAN .

¿No es un cambio de ruptura?

Tal vez no sea solo un cambio importante, sino que hace imposible cualquier lógica transaccional en los SP, ya que nunca podemos revertir nuestra transacción en el procedimiento almacenado utilizando ROLLBACK TRAN (nota: no hay transacciones anidadas en SQL Server), por lo que una reversión retrocede a @@TRANCOUNT cero. Como estábamos en una transacción porque obtuvimos EF 6, el "Recuento de transacciones después de EJECUTAR indica un número que no coincide con las instrucciones BEGIN y COMMIT. Recuento anterior = 1, recuento actual = 0." error estándar de SQL Server.

Por favor, no me preguntes por qué quiero llamar a procedimientos almacenados. Tengo cientos, y todos ellos están usando la lógica TRY ... COMMIT ... CATCH ROLLBACK .

¿Alguna idea de cómo puedo evitar que EF 6 haga esto?


Como dijo crokusek, puede establecer ese indicador para deshabilitar las transacciones para SP.

Si está utilizando una biblioteca de inyección de dependencia (DI), puede configurarla de esta manera (estoy usando el Inyector simple):

public partial class Startup { public Container ConfigureSimpleInjector(IAppBuilder app) { var container = new Container(); // Configure OWIN and Identity Framework ... // Configure persistence container.RegisterPerWebRequest<FakeDbContext>(() => { var fakeDbContext = new FakeDbContext(); fakeDbContext.Configuration.EnsureTransactionsForFunctionsAndCommands = false; return fakeDbContext; } // Register other services ... container.Verify(); // For MVC DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); return container; } }


En EF 6.1.2, una bandera controla el comportamiento. La configuración de Asegúrese de TransaccionesParaFuncionesAndCommands en falso afectará a los SP que se han importado en una entidad (estos llaman ExecuteFunction () internamente).

using (SomeEf6Context ctx = NewContext()) { ctx.Configuration.EnsureTransactionsForFunctionsAndCommands = false; // Call an imported SP }

La configuración no afectará ninguna llamada a SaveChanges ().

Enlace MSDN


Existe una sobrecarga del método ExecuteSqlCommand que evita este comportamiento:

db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, sql, parameters);


Solo para contribuir, estoy usando Unity como DI, EF 6.1.3 y la base de datos primero y recibí el mensaje: "No se permite la nueva transacción porque hay otros subprocesos que se ejecutan en la sesión" cuando llamé a un procedimiento o una función mapeado en mi archivo edmx. La opción InsuranceTransactionsForFunctionsAndCommands = false solucionó el problema. La solución de Max Zerbini también funcionó, pero tendría que usar esa forma para cada llamada de procedimiento.