transaction practices framework best c# linq linq-to-sql transactions

c# - practices - TransactionScope vs Transaction en LINQ to SQL



entity framework transaction best practices (5)

Creo que son fundamentalmente los mismos que la clase TransactionScope se interconectará con la conexión subyacente de ADO.NET para crear y confirmar o revertir la transacción. Que la clase TransactionScope acaba de crearse para que el trabajo con ADO.NET sea más limpio.

Editar: Aclarando mi afirmación con respecto a la adición de casperOne, TransactionScope creará la transacción y la conexión verá la transacción que fue creada por TransactionScope y la usará, ya que está disponible para ella.

¿Cuáles son las diferencias entre el patrón clásico de transacción en LINQ to SQL como:

using(var context = Domain.Instance.GetContext()) { try { context.Connection.Open(); context.Transaction = context.Connection.BeginTransaction(); /*code*/ context.Transaction.Commit(); } catch { context.Transaction.Rollback(); } }

frente al objeto TransactionScope

using (var context = Domain.Instance.GetContext()) using (var scope = new TransactionScope()) { try { /*code*/ scope.Complete(); } catch { } }


Linq2SQL usará una transacción implícita. Si todas sus actualizaciones se realizan dentro de un solo envío, es posible que no necesite manejar la transacción usted mismo.

De la documentación (énfasis mío):

Cuando llama a SubmitChanges, LINQ to SQL comprueba si la llamada está en el ámbito de una transacción o si la propiedad de transacción (IDbTransaction) está configurada en una transacción local iniciada por el usuario. Si no encuentra ninguna transacción, LINQ to SQL inicia una transacción local (IDbTransaction) y la usa para ejecutar los comandos SQL generados. Cuando todos los comandos SQL se han completado con éxito, LINQ to SQL confirma la transacción local y regresa.


Se debe tener en cuenta que cuando se usa TransactionScope no es necesario el constructo try/catch que tiene. Simplemente debe llamar a Complete en el alcance para comprometer la transacción cuando se sale del alcance.

Dicho esto, TransactionScope suele ser una mejor opción porque le permite anular llamadas a otros métodos que podrían requerir una transacción sin tener que pasar el estado de la transacción.

Al invocar BeginTransaction en el objeto DbConnection , debe pasar ese objeto transaccional si desea realizar otras operaciones en la misma transacción, pero con un método diferente.

Con TransactionScope , mientras el alcance exista, manejará todo lo que se registre con la Transaction actual en el hilo, haciendo que su código sea más limpio y más fácil de mantener.

Además de eso, tiene el beneficio adicional de poder usar otros recursos que pueden participar en las transacciones, no solo la conexión a la base de datos.

Debe tenerse en cuenta que, en situaciones en las que necesita aprovechar al máximo sus conexiones y operaciones de base de datos, es posible que no desee utilizar TransactionScope ; incluso contra una única base de datos, se ejecuta la posibilidad de que se utilice el Coordinador de transacciones distribuidas y que la transacción se convierta en una transacción distribuida (incluso para una única conexión de base de datos).

En estos casos, mientras entorpece su diseño, es posible que desee considerar pasar una transacción específica de conexión.

O bien , si sabe que utilizará un recurso de forma coherente (y en el mismo hilo), puede crear una clase que haga referencia: cuente su conexión / transacción.

Crearías una clase que en la construcción, crea tu recurso / incrementa el recuento. También implementaría IDisposable (en el que disminuirías / liberar / confirmar / abortar cuando el recuento es cero) y almacenar el recuento en una variable que tenga el ThreadStaticAttribute aplicado.

Esto le permite separar la gestión de transacciones del código lógico y aún conservar un recurso singular con bastante eficacia (en lugar de escalar a una transacción distribuida).


TransactionScope proporciona administración unificada para todos los administradores de recursos (servidor SQL, directorio activo, sistema de archivos, ...). Además, uno puede escribir su propio administrador de recursos: código que detecta el alcance de la transacción, se une a él y funciona exactamente como lo hace el servidor SQL: confirma o revierte los cambios como otros participantes de la transacción. Creía que TransactionScope es convencional y olvidé las transacciones nativas de MS SQL hasta que falló en una gran trampa: Windows Server 2008 Edición WEB viene con un servicio de Coordinador de transacciones distribuidas restringido y el alcance de transacción funciona solo en una sola computadora. Su aplicación ASP.NET fallará en este sistema si IIS y SQL Server están instalados en diferentes computadoras. Tenga en cuenta que la mayoría de los proveedores de dominio público suministran la edición WEB de Windows Server y el servidor SQL se encuentran en servidores separados. Esto significa que debe trabajar con transacciones nativas utilizando la gestión de transacciones explícita ...


Una gran diferencia (lección aprendida de la manera más difícil): TransactionScope usa MS DTC para la administración de transacciones.

Si su aplicación tiene que administrar solo la transacción de la base de datos, y no hay servicios o llamadas remotas, puede omitir los posibles problemas relacionados con MS DTC mediante el uso de transacciones nativas de las bases de datos (DbTransactions).