architecture ado.net transactions n-tier system.transactions

architecture - Estrategias para evitar la escalada de transacciones en System.Transactions



ado.net n-tier (4)

Recomiendo escribir una clase contenedora para administrar conexiones, transacciones, objetos de comando, eso es todo lo que hace DB. Es una especie de nHibernate muy liviano. Esta clase proporcionaría métodos para executeStatement (...), executeQuery (...), addParameter (...), startTransaction (...) y así sucesivamente.

Al iniciar una transacción, puede proporcionar algún identificador (si es necesario) que podría vincular todas las solicitudes siguientes con respecto a la misma transacción. Esta clase contenedora entonces mantendría un mapeo estático a qué transacción se está ejecutando con qué conexión y usaría automáticamente el correcto o crear uno nuevo según sea necesario.

Obtendrá algunas características adicionales de este enfoque, ya que habrá centralizado todo su material de persistencia:

  • registrar fácilmente todas las declaraciones para la depuración, pruebas de rendimiento
  • lógica automática de reintento en problemas de bloqueo / red
  • cambio más simple de proveedor de DB
  • Básicamente, algunas de las cosas que obtienes con marcos de persistencia como nHibernate, pero más ligeras y no tan sofisticadas

Entonces, de acuerdo con la respuesta a mi pregunta anterior , las transacciones se elevan del LTM al DTC si se abren múltiples conexiones durante una transacción, incluso si todas las conexiones tienen la misma cadena de conexión.

Entonces, mi siguiente pregunta es, ¿qué estrategias podría emplear para evitar esta "característica"? Me parece que, en función del uso de recursos, quiero asegurarme de que el LTM se use tanto como sea posible. La única manera que puedo pensar de hacerlo, en una capa de lógica empresarial orientada a objetos, es hacer un objeto de conexión estática de nivel de solicitud en la capa de acceso a datos y compartirlo entre llamadas hasta que se complete la solicitud (el conocimiento implícito aquí es que las entidades objeto de negocio son discretas y no saben en qué orden se llamarán, además es el hecho de que uno no desearía burbujear un objeto de conexión hasta la capa de objeto de negocio ya que eso sería detalles de implementación de almacenamiento de datos sangrado en otra capa).

¿Alguien más tiene alguna idea que no arruine por completo la encapsulación de capas de un sistema de n niveles?


Como dijo Casper, evitar el DTC puede ser prematuro, aunque es un peso significativo. Podría implementar sus conexiones utilizando fábricas estáticas para que simplemente devuelva nuevos objetos, y luego, si determina que tiene un problema, podría implementar un mecanismo que pueda almacenar las transacciones en un TLS (o httpcontext si está en ASP). Y no tiene que cambiar ningún código.

Esta pregunta se ha realizado y respondido, pero no puedo encontrarla cuando lo haga. Actualizaré esto.


Tengo que preguntar, ¿cuál es el motivo por el cual me esfuerzo tanto para evitar el DTC? No se menciona en esta o en la respuesta anterior en cuanto a por qué, y parece que podría estar padeciendo el síndrome de optimización prematura.


Lo que he usado es una clase de TransactionHelper que actualiza todos los comandos en un TableAdapter para reemplazar la conexión y la transacción con los del TableAdapter que inicia la transacción. Puede encontrar algún código que haga esto , que puede adaptar según sea necesario, en el blog de Scott Lanford, CodeExperiment . Ryan Whitaker tiene un enfoque similar .

Tenga en cuenta que desde que me mudé a usar LINQToSQL ya no tengo este problema. Es posible que desee considerar el uso de LINQToSQL o nHibernate como una solución alternativa. Cualquiera de ellos tendría un buen soporte para las transacciones locales.