InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
También puedes ver ...
SET IDENTITY_INSERT ON y LinqToSQL
Creando cadenas de conexión ConnectionStrings en .net 3.5 o visual Studio 2008 usando SqlConnectionStringBuilder
Migración de WSE a WCF (Web Services de 2005 a 2008)
Generar archivos PDF con C#
LinQ To SQL - Un ejemplo sencillo
Cómo activar Intelisense (autocompletado) en el Web.config
Leer un campo XML de SQL Server 2005 con C#
TripleDES - Un ejemplo practico en C#
Mostrar un GridView dentro de un DataList
String.Format

Afiliados
La Web del programador
MundoProgramacion


 

TransactionScope - Simplificando el trabajo con transacciones.

A partir del Framewrok 2.0 tenemos a nuestra disposición el objeto TransactionScope, que permite simplificar el trabajo con transacciones. Especialmente llamativo es la capacidad de promocionar la transacción a un entorno de transacciones distribuidas (MS DTC - COM+) de forma casi transparente .

Vamos a empezar con un ejemplo sencillito, de esos que no tienen que fallar nunca. Lo primero que debemos hacer es añadir una referencia a System.Transactions en nuestro proyecto.

Sobre una base de datos de prueba, creamos una nueva tabla para nuestro ejemplo.

 

CREATE TABLE

Persona

(CodPersona int IDENTITY,

Nombre varchar(50),

Apellido1 varchar(100),

Apellido2 varchar(100),

FechaNacimiento datetime,

CONSTRAINT PK_Persona PRIMARY KEY (CodPersona)

)

Para acceder a los datos vamos a utilizar LinqToSQL, por lo que añadimos un nuevo archivo de este tipo a nuestro proyecto. Por supuesto también podríamos trabajar con el modelo clásico de ADO.NET. Podemos ver como añadir clases de LinqToSQL a nuestro proyecto desde este enlace:
http://www.devjoker.com/contenidos/Articulos/326/LinQ-To-SQL--Un-ejemplo-sencillo.aspx

Ahora creamos un formulario - con un único botón - y añadimos el siguiente código al evento click del botón.

 

using (TransactionScope transactionScope = new TransactionScope())

{

try

{

AddData();

transactionScope.Complete();

MessageBox.Show("OK");

}

catch (Exception ex)

{

MessageBox.Show(ex.Message,

"Error - Se deshacen los cambios");

}

}

Con esto estamos envolviendo el código con un objeto TransactionScope - que crea a su vez una transacción controlada por el componente de Windows denominado LTM (Lightweight Transaction Coordinator) - es lo que se conoce como ambito o contexto de la transacción.

Posteriormente llamamos a un método que se encarga de grabar los registros en la base de datos y si todo ha ido bien confirmamos las transaccion con el método Complete(). Como vemos todo muy simple.

El método AddData es un simple bucle que inserta 100 registros en la base de datos. Lo vemos - no debemos tener ningún tipo de problema si hemos leido el artículo de LinqToSql que hemos mencionado antes.

 

private void AddData()

{

using (DataDataContext ctx = new DataDataContext())

{

for (int i = 0; i < 100; i++){

Persona p = new Persona();

p.Nombre = String.Format("Nombre {0}", i);

p.Apellido1 = String.Format("Apellido1 {0}", i);

p.Apellido2 = String.Format("Apellido2 {0}", i);

p.FechaNacimiento = DateTime.Now.AddMonths(i * -1);

ctx.Personas.InsertOnSubmit(p);

}

ctx.SubmitChanges();

}

}

Si consultamos los datos de la tabla Persona - que creamos en nuestra base de datos al principio del artículo -tendremos algo así:

CodPersona  Nombre     Apellido1      Apellido2       FechaNacimiento
----------- ---------- -------------- --------------- -----------------------
1           Nombre 0   Apellido1 0    Apellido2 0     2008-07-14 23:26:43.907
2           Nombre 1   Apellido1 1    Apellido2 1     2008-06-14 23:26:43.907
3           Nombre 2   Apellido1 2    Apellido2 2     2008-05-14 23:26:43.907
4           Nombre 3   Apellido1 3    Apellido2 3     2008-04-14 23:26:43.907
5           Nombre 4   Apellido1 4    Apellido2 4     2008-03-14 23:26:43.907
6           Nombre 5   Apellido1 5    Apellido2 5     2008-02-14 23:26:43.907 
...

Todo ha ido bien y no hemos debido tener ningún problema.

Ahora queremos comprobar que cuando las cosas fallan los cambios se deshacen correctamente. Para ello incluimos un nuevo método, que llamará al método de añadir registros (y que acabamos de ver que funciona correctamente) y una finalizada la inserción de datos lanzará un error..

 

private void AddDataWithError()

{

AddData();

throw new ApplicationException("Error provocado");

}

Y modificamos nuestro código para que se llame al método que lanza el error. 

 

using (TransactionScope transactionScope = new TransactionScope())

{

try

{

AddDataWithError();

transactionScope.Complete();

}

catch (Exception ex)

{

MessageBox.Show(ex.Message,

"Error - Se deshacen los cambios");

}

}

Podemos comprobar que la aplicación muestra el mensaje de error y revierte correctamente las inserciones. Para ello insertamos un punto de detención (F9) en la línea que muestra el MessageBox de error. Cuando la ejecución de códgio se pare en el punto de detención, consultamos la base de datos con la siguiente instrucción:

 

SELECT * FROM Persona(NOLOCK)

En este momento podemos observar que se han inserado 100 nuevos registros, pero la transacción aún no ha sido confirmada - por eso debemos especificar NOLOCK para poder ver los datos. Continuamos la ejecución del código y volvemos a lanzar la consulta. La transacción se ha deshecho correctamente y los datos no se ha grabado. Funciona perfectamente.

Pero,¿como se está haciendo commit? ¿ donde se está haciendo el Rollback ? Cuando se crea una transacción utilizando TrasactionScope, se crea una transacción ligera que será controlada por un componente de Windows denominado LTM (Lightweight Transaction Coordinator),  es este componente el encargado de controlar la transacción. Por lo tanto, no es necesario hacer Rollback, una vez que salimos del ambito de la transacción los cambios se deshacen automanticamente si no han sido confirmados. Es decir, cuando salimos de la clausula using que contiene a TransactionScope.

Cuando en la transacción intervienen más de un recursos transaccional (diferentes bases de datos, colas ...) la transacción es promocionada, dejando de ser una transacción ligera - controladas por el LTM - y se convierte en una transacción distribuida - coordinada por el MS DTC (Distributed Transaction Coordinator). Es una técnica realmente potente que abordaremos en posteriores articulos. Como inveniente diremos que el coordinador de transacciones distribuidas en un componente COM+ y que por lo tanto se hace uso de interoperatividad con COM+ (y los problemas que ello puede suponer).

Saludos, DJK


 Versión para imprimir  Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



 Versión para imprimir

TransactionScope - Simplificando el trabajo con transacciones.
Autor: Pedro Herrarte Sánchez
Visitas: 1135 Fecha de publicación: 11/08/2008
Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación.

Posee mas de diez años de experiencia trabajando para las principales empresas de España.

Es especialista en tecnologías .NET, entornos Web, bases de datos (SQL Server y ORACLE) e integración de sistemas.

Es experto en desarrollo (C#, ASP.NET, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE).

Es fundador, diseñador y programador de www.devjoker.com.




Visitas: 304 | Comentarios: 0 | Archivo: Articulos
Categorias: ASP.NET|CSS|ASP.NET
Visitas: 137 | Comentarios: 0 | Archivo: Articulos
Categorias: TFS
Visitas: 101 | Comentarios: 5 | Archivo: Articulos
Categorias: TFS
Visitas: 430 | Comentarios: 4 | Archivo: Articulos
Categorias: Transact-SQL|LinQ
Visitas: 1448 | Comentarios: 6 | Archivo: Articulos
Categorias: Visual Basic .NET|C#|ASP.NET|ASP.NET|Programación|ADO.NET
27/09/2008 Navegando ....
Visitas: 239 | Comentarios: 0 | Archivo: Articulos
Categorias: Humor
Visitas: 611 | Comentarios: 0 | Archivo: Articulos
Categorias: Visual Basic .NET|C#|ASP.NET|ASP.NET|Programación|WCF
Visitas: 2576 | Comentarios: 4 | Archivo: Articulos
Categorias: C#
Visitas: 464 | Comentarios: 0 | Archivo: Articulos
Categorias: JavaScript|ASP.NET
Visitas: 1072 | Comentarios: 0 | Archivo: Articulos
Categorias: Windows XP|Linux|Windows Vista

Útimos temas recibidos en los foros ...
Enviar un email con C# utilizando .Net FrameWork 2.0 con logo... por Moises ... [ASP.NET] 1 21/11/2008
Crystal reports XI Release 2 y asp.net por mvargas ... [ASP.NET] 0 21/11/2008
Enviar un email con C# utilizando .Net FrameWork 2.0 por Moises ... [C#] 0 21/11/2008
Cuestión de BFILE. por Megatron ... [ORACLE] 0 21/11/2008
Enviar email por Dol ... [ASP.NET] 5 21/08/2007
*******PREGUNTA********: por T.S.U.En Informatíca ... [Visual Basic 6.0] 5 17/03/2008
Programar tareas en oracle. por Rodrigo ... [ORACLE] 0 21/11/2008
fechas con datatimepicker por peyin ... [Visual Basic .NET] 3 20/11/2008
agregar datos de un gridview a un textbox por jhors ... [ASP.NET] 3 19/09/2007
Select de sql en c# por Stuart ... [C#] 1 20/11/2008
Manual en Español de SQL Navigator for Oracle por Maira ... [ORACLE] 12 30/03/2008
Como mandar mensaje a Celular por Pako ... [C#] 40 13/03/2007

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
19/09/2007 Triggers en Transact SQL    forma parte de...Tutorial de Transact SQL
22/10/2005 Introducción SQL    forma parte de...Tutorial SQL
19/08/2006 Virtualización. Maquinas Virtuales.
01/01/2006 Consultas agregadas    forma parte de...Tutorial SQL
27/09/2008 Navegando ....
09/05/2006 Como leer XML con C#
10/10/2006 Como conectar a ORACLE con Java
03/10/2006 Ocultación de miembros    forma parte de...Tutorial C#
03/10/2006 Definición de clases    forma parte de...Tutorial C#
27/10/2006 Eventos    forma parte de...Tutorial C#

 

Encuesta
¿A que perfil te adaptas mejor?
[Ver] [Votar]