new framework ejemplo begintransaction .net transactions transactionscope

.net - framework - transactionscope vs begintransaction



Anidado/niƱo TransactionScope Rollback (1)

Probablemente no te va a gustar esta respuesta, pero ...

Votar dentro de un ámbito anidado

Aunque un ámbito anidado puede unirse a la transacción ambiental del ámbito raíz, la llamada Completa en el ámbito anidado no afecta al ámbito raíz. Solo si la totalidad de los ámbitos desde el alcance raíz hasta el último voto de alcance anidado para confirmar la transacción, se realizará la transacción.

(De Implementar una Transacción Implícita usando el Alcance de la Transacción )

La clase TransactionScope desafortunadamente no proporciona ningún mecanismo (que yo sepa) para segregar unidades de trabajo. Es todo o nada. Puede evitar que se produzca cualquier transacción en una unidad específica de trabajo utilizando TransactionScopeOption.Suppress , pero probablemente no sea lo que desea, ya que perdería la atomicidad de lo que esté dentro de ese alcance.

Solo hay una transacción "ambiental" cuando utiliza un TransactionScope . Una vez que un TransactionScope se elimina o se recopila sin que se Complete ejecución, la transacción ambiental completa se retrotrae; eso es todo, se acabó el juego.

De hecho, SQL Server no es compatible con verdaderas transacciones anidadas, aunque es posible (aunque algo no intuitivo) lograr el mismo resultado final con el uso adecuado de las declaraciones SAVE TRAN . Reimplementar esta lógica como un procedimiento almacenado (o varios de ellos) podría ser su mejor opción si necesita este comportamiento en particular.

Estoy intentando anidar TransactionScopes (.net 4.0) como anidaría Transactions en SQL Server, sin embargo, parece que funcionan de manera diferente. Quiero que mis transacciones secundarias puedan revertirse si fallan, pero permitir que la transacción principal decida si comprometer / deshacer toda la operación. El problema es que cuando se produce la primera finalización, la transacción se revierte. Me doy cuenta de que completar es diferente comprometerse.

Un ejemplo muy simplificado de lo que estoy tratando de hacer:

static void Main(string[] args) { using(var scope = new TransactionScope()) // Trn A { // Insert Data A DoWork(true); DoWork(false); // Rollback or Commit } } // This class is a few layers down static void DoWork(bool fail) { using(var scope = new TransactionScope()) // Trn B { // Update Data A if(!fail) { scope.Complete(); } } }

No puedo usar las opciones Suprimir o RequiereNuevo ya que Trn B se basa en los datos insertados por Trn A. Si uso esas opciones, Trn B está bloqueado por Trn A.

¿Alguna idea de cómo lo haría funcionar, o si es posible usar el espacio de nombres System.Transactions?

Gracias