martes, abril 04, 2006

Transacciones

Estoy ahora con la serie C del curso de ADO.NET: hay novedades suficientes en la 2.0 como para redactar directamente esta parte para la nueva versión. Voy a mantener el material original, centrado en los adaptadores de datos, porque sigo creyendo que es esencial dominar el funcionamiento de SqlDataAdapter para trabajar bien con los nuevos table adapters. Pero es en esta serie donde voy a incluir el nuevo sistema de adaptadores de tablas, por lo que tendré que añadir unos cuantos ejercicios más.

Hay otra novedad indispensable en ADO.NET: el nuevo espacio de nombres System.Transactions. Es probable que el soporte para transacciones en ADO.NET 1.0 haya sido tan malo (sí, era muy malo) porque ya estaba entre los planes la adición de esta funcionalidad. La idea es muy sencilla: ¿quiere iniciar una transacción? Cree un objeto de la clase TransactionScope con la ayuda de una instrucción using. Todo el código que se ejecute mientras el objeto creado está vivo, estará "protegido" por la transacción. No hace falta que ese código se ejecute dentro del mismo método. La transacción se convierte en una especie de atributo global del proceso, durante todo el tiempo en que está activa. Cuando quiera confirmar la transacción, llame al método Commit de la instancia creada. Si por el contrario, abandona la sección protegida sin confirmar, los efectos de las operaciones realizadas se cancelan de forma automática.

¿A qué se parece este sistema? Efectivamente, ¡se parece a las transacciones "declarativas" de COM+! Naturalmente, la implementación de esta funcionalidad en .NET 2.0 es mucho más fácil que la implementación en COM+. En COM+ se utiliza una técnica compleja que intercepta llamadas en tiempo de ejecución. System.Transactions, por el contrario, al estar contenido dentro de la plataforma, es mucho más eficiente, sobre todo cuando no hay que lidiar con transacciones distribuidas entre distintos administradores de recursos.

Puede que, si no conoce COM+, no comprenda el motivo de mi entusiasmo. Intentaré explicarlo en dos párrafos: En cierto sentido, el manejo de transacciones se parece al manejo de excepciones. ¿En qué sentido? ¡En que no se puede encapsular! Ambas son tareas que se deben distribuir a lo largo y ancho del código fuente. Esta es una consecuencia indeseada asociada al concepto de composición modular. Suponga que escribimos un método para hallar la raíz cuadrada. Exigimos que nos proporcionen un valor positivo. ¿Qué hacer si alguien, deliberadamente o por error, nos pasa un número negativo? Cualquier cosa que hagamos es mala... ¡porque, al tratarse de un método sumamente reutilizable, no sabemos dónde ni cómo se va a usar! Lo único sensato: disparar una excepción, y dejar la responsabilidad de su manejo a quien ensamble el método en un sistema más complejo. El, o ella, sabrán mejor que nosotros cuál será la mejor política.

¿Y qué ocurre con las transacciones? Usted escribe una rutina para cargar un importe a una tarjeta de crédito. ¿Debe encerrarla en una transacción? Puede que la rutina termine usándose por separado; puede que la rutina forme parte, finalmente, de una operación mucho más compleja. Y, lo más complicado y a la vez real, puede que ocurran las dos cosas, y que la rutina sea utilizada en los contextos más diversos. Tiene sentido hablar del éxito local del cargo en tarjeta. Si esta operación falla, y en el contexto que se ejecuta no existe una alternativa (como el pago por transferencia), la operación debe fallar. Pero si triunfa, esto no significa que el proceso que la engloba haya también triunfado. En todos caso, se tratará de un voto a favor de una de las partes del sistema.

Por este motivo son importantes sistemas como COM+ y el nuevo sistema en .NET: permiten "componer" operaciones que trabajan con transacciones. Y esto significa que es mucho más sencillo crear módulos verdaderamente reutilizables.

8 Comments:

Blogger PabloNetrix said...

Yo recuerdo que, en un proyecto que hice para una cadena de perfumerías, el tema "transacción" quedaba un poco sui géneris, es decir, primero siempre efectuaba todas las operaciones en las cuales yo tenía el control (las que atacaban la BBDD de la empresa), y DESPUES las operaciones "externas", sobre las que no tenía ningún control sobre el resultado (tu ejemplo del pago con tarjeta). Si fallaba esa operacion externa, entonces forzaba un rollback (que no era tal, sino "a mano" borrando los registros insertados de los cuales me guardaba el ID en una struct en memoria... porque no se fiaban mucho del tema integridad referencial y borrados en cascada).

Aunque la operación de pago con tarjeta se puede anular, siempre es más pesado tener que hacerlo. Además de que el tiempo de respuesta de los servidores del banco se va sumando y si hay fallos de comunicaciones, se puede montar un buen pollo.


Saludos

jueves, abril 06, 2006 10:54:00 a. m.  
Anonymous Anónimo said...

Está muy bien todo el .NET, pero hasta ahora, Microsoft ha ido demostrando que sus "grandes descubrimientos" para el futuro de la programación en poco tiempo se quedan en nada, porque se vuelve a plantear todo de nuevo y vuelve a hacer "grandes descubrimientos" y todo lo que había dicho cambia radicalmente y casi nada es compatible. Vale la pena correr detras del carro de MS?.
No valdría la pena pensar en la programación con linux? o al menos con bases de datos libres con firebird?.

jueves, abril 06, 2006 12:31:00 p. m.  
Blogger PabloNetrix said...

Pues antonio, no estaría mal que nombrases dos o tres de esos "grandes descubrimientos que se han quedado en nada". Además, eso de que en poco tiempo "se vuelve a plantear todo de nuevo" no es, ni mucho menos, patrimonio exclusivo de Microsoft. Pero es que además, si no fuese así, si no se produjeran de vez en cuando "revoluciones" en vez de "evoluciones", la Evolución como tal (entendida como un concepto global) no habría llegado hasta donde está.

Por ponerte un ejemplo: Los monitores. ¿Las pantallas TFT son una revolución o una evolución de las CRT de toda la vida? Yo creo que lo primero, porque la tecnología de una y de otra poco tienen que ver (y no me negarás que para trabajar no hay NADA mejor que una pantalla TFT). Sin embargo, el camino que va desde los televisores de válvulas hasta los últimos modelos de 100Hz sí que creo que es más una evolución: De la válvula al transistor, del transistor al circuito integrado, etc.

Y para programar en Linux no se me ocurre nada mejor que Mono (que no deja de ser .NET) o bien Portable.NET, y en cuanto a Firebird, pues hay Proveedores de datos que se usan con .NET con lo cual no veo el problema por ningún sitio (cabe recordar que la plataforma .NET es gratuita así como muchos IDEs como SharpDevelop).

Saludos

jueves, abril 06, 2006 4:14:00 p. m.  
Anonymous Anónimo said...

Hola
Pues va a ser que quiero hacer rabiar a Ian, pero a mi si que se me ocurre algo mejor que Mono para programar en linux y es Java.(Que conste que profesionalmente llevo 29 meses programando solo en .Net,pero quien quiere programar en Mono teniendo que contrastar todo el rato si una determinada funcionalidad esta o no implementada;cuando microsoft de soporte a .net en linux
me lo plantearé.)
Ademas, si hablamos de entornos de desarrollo, prefiero Eclipse a sharpdevelop (no es para molestar otra vez a Ian),pero es que, independientemente de si a los programadores nos perjudica o no su filosofia, lo cierto es que el entorno es bueno.

Saludos

domingo, abril 09, 2006 6:23:00 p. m.  
Anonymous Anónimo said...

Esta nueva forma de usar transacciones, a parte de facilitarnos la vida, ¿permite, como hace COM+, el uso de transacciones distribuidas? Porque como me digas que si me olvido de COM+ para un proyecto que tengo en mente (el resto de caracteristicas no son claves para mi)

sábado, abril 29, 2006 1:43:00 a. m.  
Blogger Ian Marteens said...

Exacto... pero tengo una mala noticia: creo que exige SQL Server 2005 (para la parte que concierne a SQL Server); en teoría, sí se podría usar con los controladores actuales para Oracle y el resto de la pandilla. A primera vista, parecía algo implementado dentro del CLR, pero he visto un par de notitas por aquí y por allá alertando del asunto. No lo he comprobado todavía.

De todas maneras, tienes los "enterprise services" desde .NET 1.1, y es bastante sencillo. Si tienes que echarle un vistazo urgente al asunto, te recomiendo un libro de Matthew McDonald editado por Microsoft Press. Es bastante claro y directo, aunque la parte sobre ADO.NET en sí es muy escueta.

Y fuera de .NET, la mejor forma de tocar COM/COM+... es el propio Delphi nativo. Ni Visual Studio 6 ni leches.

jueves, mayo 04, 2006 3:02:00 p. m.  
Anonymous Anónimo said...

LEI DESDE HACE UN BUEN TIEMPO SU PAGINA Y ARCHIVOS ADJUNTOS LOS CUALES ME PARECE MUY BIEN QUE TENGA UNA PAGINA DE ESTAS CARACTERISTICAS TAN DIDACTICAS EN LA WEB SOLO QUISIERA OBTENER ALGUNOS CONSEJOS EN PROGRAMACION C# AVANZADA MI CORREO ES ABRAHAM-AA@LYCOS.COM Y AGRADECERTE POR TAN DIDACTICA LABOR

sábado, junio 17, 2006 8:14:00 p. m.  
Blogger Jaume P said...

Antes de programación avanzada, querido amigo, te aconsejaría que aprendieras a publicar comentarios en minúsculas, en caso contrario DA LA IMPRESIÓN DE GRITAR.
Sobre programación C# avanzada, ejecuta la función:

public void AvanzarEnProgramacion()
{
MessageBox.show("comprate libros básicos");
}

martes, julio 12, 2011 3:47:00 p. m.  

Publicar un comentario

<< Home