Pregunta TransactionScope vs Transaction en LINQ to SQL


¿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
    {
    }
}

74
2018-02-12 17:50


origen


Respuestas:


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.


34
2018-02-12 18:36



Cabe señalar que cuando se utiliza el TransactionScope no hay necesidad de try/catch construcción que tienes. Simplemente tienes que llamar Complete en el alcance para comprometer la transacción cuando se sale del alcance.

Habiendo dicho eso, TransactionScope generalmente es 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.

Cuando llamas BeginTransaction sobre el DbConnection objeto, debe pasar ese objeto transacción si desea realizar otras operaciones en la misma transacción, pero en un método diferente.

Con TransactionScope, mientras el alcance exista, manejará todo lo que se registre con la corriente Transaction 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, si sabe que usará un recurso de manera 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 / comprometer / abortar cuando el recuento es cero), y almacenar el recuento en una variable que tiene ThreadStaticAttribute aplicado a ella.

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).


72
2018-02-12 18:41



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).


20
2017-10-04 22:52



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í que TransactionScope es convencional y olvidé las transacciones nativas de MS SQL hasta que fracasé 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 ...


6
2018-05-18 13:39



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 declaración con respecto a la adición de CasperOne es el TransactionScope el que creará la transacción y la conexión verá la transacción creada por el TransactionScope y la usará, ya que está disponible para él.


4
2018-02-12 18:16