19 diciembre 2006

Transas con TransactionScope

Sobre las transas, hay un poco de miedo ante la utilización del nuevo TransactionScope de .net 2.0. Se basan en System.Transaction, un nuevo espacio de nombres que abstrae y centraliza el manejo de transacciones, alejándose de la concreción de las DbTransaction. Esto, que ya suena a pérdida de rendimiento, se ve agravado por el uso de MS DTC (coordinador de transacciones distribuidas), un servicio de Windows para la realización de transacciones que afectan a diferentes orígenes transaccionales (por ejemplo, transas que involucran distintas bases de datos). Muchos advierten de que el uso de MS DTC es una grave pérdida de rendimiento en la mayoría de los casos, ya que su potencia no suele ser necesaria.
El artículo con que decoro esta entrada, junto con este otro que se basa en el anterior, me aclaró mucho las cosas. Deja claro que sobre SQL Server 2000 es cierta esta afirmación, todo uso de TransactionScope delega en una transacción distribuida de DTC. Pero en SQL Server 2005 no es así, ya que incluye las nuevas transacciones promocionables, que pueden comenzar siendo transas locales para luego promocionar cuando sea necesario a transas distribuidas. Por cierto, una cosa que no me queda clara es qué entendemos por una transa local, si incluye el acceso a una única base de datos de la red o sólo en el propio equipo. Cuando lo averigue comentaré esta entrada.
Por supuesto, lo que se comenta para SQL Server 2000 supongo que será de aplicación al resto de motores de bases de datos, que no aprovecharán el Gestor de transacciones ligeras (Lightweight Transaction Manager) para el trabajo con transas promocionables. Ya he podido comprobar que con el motor Jet de Access, no sólo es así, sino que se prohíbe la utilización de transas de contexto (TransactionScope), si es detectada una se aborta el comando.

Así que vuelvo a plantearme la razón de utilizar TransactionScope: en primer lugar me parece una estructura de código más sencilla y de un alto nivel, al definir un ámbito de código donde toda operación es incluida en la transacción. Por otro lado me acerca a la interoperabilidad entre distintos motores, pero por mis pruebas actuales TransactionScope sólo me ha funcionado con SQL Server (y eficientemente con 2005), por lo que esta razón comienza a descolgarse. Y hay una nueva tercera razón: la realización de transacciones donde están involucradas distintas bases de datos, caso no frecuente pero sí posible (de hecho tengo algunos procesos críticos en que hay involucradas distintas bases de datos).

Por ello, opto por una solución combinada: creo un objeto propio AmbitoTransaccional, que en función del motor de base de datos utiliza transacciones de nivel de base de datos, o bien una instancia de TransactionScope. Así puedo seguir ofreciendo una estructura de código elegante y moderna, a la vez que funciona para cualquier motor.

Por cierto, para poder utilizar TransactionScope, es necesario activar MSDTC para permitir conexiones de cliente entrantes y salientes, tanto en el cliente como en el servidor, como se describe en los libros en pantalla de SQL Server. El procedimiento viene bien explicado en una respuesta que copio (tengo el enlace pero han quitado la página):
(1) Arranca: Herramientas administrativas - Servicios de componentes.
(2) Expande: Raíz de la consola - Equipos - Mi PC.
(3) Pulsa con el botón derecho del ratón en "Mi PC" y elige "Propiedades".
(4) En el cuadro "Propiedades de Mi PC" ficha "MSDTC" pulsa el botón "Configuración de seguridad".
(5) En el cuadro "Configuración de seguridad" activa lo siguiente:
a) Acceso a DTC desde la red
1) Permitir clientes remotos.
b) Comunicación del administrador de transacciones:
1) Permitir entrantes
2) Permitir salientes
3) No se requiere autenticación
4) Habilitar transacciones con el protocolo TIP
c) Habilitar transacciones XA

Lo que necesito es documentación acerca de como hacer esto automáticamente, quizá desde un programa de instalación.

Por cierto, y para terminar, dejo un artículo donde se habla bien de TransactionScope (por fin, me ha costado encontrarlo y aún más leerlo, aún no lo he hecho).

Etiquetas: