Implementación n capas

30/03/2008 - 15:25 por Guillermo Peralta | Informe spam
Hola;

Tengo una duda relacionada con la implementación en "n" capas.

Supongamos una capa Negocio y una capa Datos, y un objeto Maestro/Detalle
como podria ser el caso de una Factura

FACTURAS
NroFactura
Fecha
Renglones //coleccion generic de Detalle de Factura


Segun lo que entiendo, la separación en capas me permite lograr que desde
Interfaz de usuario, simplemente llamar a Negocio.Guardar (oFactura) y nada
mas.

Desde Negocio llamo a mi capa de datos, lo que en pseudocodigo queda algo
como:

<Inicio>
<Transaction>
Datos.Factura.Guardar (oFactura) //guardo el encabezado

Datos.DetalleFactura.Guardar (oFactura.Renglones) //guardo el
detalle
<FinTransaction>
<Fin>

La Capa de Datos es la que se encarga de llamar a los Command
correspondientes segun el proveedor de datos que este trabajando (SQL,
Oracle, etc.)

Las preguntas son (por fin!),
¿En qué momento se debe abrir la conexion? Desde la capa de Negocio o cada
objeto de Datos debe abrir/cerrar su conexion?
¿Como es en este caso el manejo de transacciones? ¿Debe ser manejada desde
la capa de Negocios? ¿Esto no hace que no sea independiente del motor de
base de datos? Es decir, desde mi capa de negocio debo tener una Refencia a
System.Data.dll. .? o solamente a MiCapaDatos.dll


Sé muy bien que no hay soluciones únicas, ni respuestas mágicas, solo
pretendo aclarar un poco más la situación.

Muchas Gracias

Guillermo

Preguntas similare

Leer las respuestas

#1 Alberto Poblacion
30/03/2008 - 17:16 | Informe spam
"Guillermo Peralta" <guillermoperalta(-a.r.r.o.b.a.-)onenet.com.ar> wrote in
message news:
[...]
Las preguntas son (por fin!),
¿En qué momento se debe abrir la conexion? Desde la capa de Negocio o cada
objeto de Datos debe abrir/cerrar su conexion?



La conexión es más bien propia de la capa de datos. No hay problema en
abrir y cerrar numerosas veces la conexión, ya que el sistema de "pooling"
se encarga automáticamente de optimizar este proceso.

¿Como es en este caso el manejo de transacciones? ¿Debe ser manejada desde
la capa de Negocios? ¿Esto no hace que no sea independiente del motor de
base de datos? Es decir, desde mi capa de negocio debo tener una Refencia
a System.Data.dll. .? o solamente a MiCapaDatos.dll



Una forma de resolverlo es implementar en capa de datos una función que
sea "ComenzarTransacción", y las correspondientes funciones para terminarla,
y llamar desde capa de negocio a esta función.

Si estás programando con .Net Framework versión 2 o superior, puedes usar
desde capa de negocio el objeto TransactionScope (en System.Transactions),
que te permite indicar el ámbito de la transacción sin tener que conocer el
proveedor de la base de datos. TransactionScope sirve para realizar
transacciones distribuidas, pero si lo usas contra Sql Server y todas las
conexiones las realizas a la misma base de datos, tiene la inteligencia
suficiente para generar una transacción local en lugar de distribuida.

Sé muy bien que no hay soluciones únicas, ni respuestas mágicas, solo
pretendo aclarar un poco más la situación.



Efectivamente, ninguna solución es mágica. Las respuestas anteriores son
solo un par de sugerencias, pero no quiere decir que siempre deba realizarse
una implementación de esta manera.
Respuesta Responder a este mensaje
#2 Guillermo Peralta
30/03/2008 - 18:44 | Informe spam
Hola Alberto;

Si estás programando con .Net Framework versión 2 o superior, puedes
usar desde capa de negocio el objeto TransactionScope (en
System.Transactions), que te permite indicar el ámbito de la transacción
sin tener que conocer el proveedor de la base de datos.



Sí, es con Net Famework 2.0 y estaba usando System.Transactions, y quiza
desde aqui es cuando se me empezo a complicar la situación, a ver si me
puedes aclarar un poco

TransactionScope sirve para realizar transacciones distribuidas, pero si
lo usas contra Sql Server y todas las conexiones las realizas a la misma
base de datos, tiene la inteligencia suficiente para generar una
transacción local en lugar de distribuida.



Entiendo que te refieres no a la misma base de datos sino a la misma
conexion abierta no?

Porque si por ejemplo tengo:

Using TransactionScope

Guardar.Factura
AbrirConexion
EjecutarComando
CerrarConexion
Fin Guardar.Factura

GuardarDetalle.Factura
AbrirConexion (*) // Aqui
EjecutarComando
CerrarConexion
Fin GuardarDetalle.Factura

Fin TransactionScope


Al Ejecutar de este modo, en el lugar indicado con asterisco, se me presenta
la execpcion "Se ha
deshabilitado el acceso de red para el administrador de transacciones
distribuidas (MSDTC). Habilite DTC para el acceso de red en la configuración
de seguridad de MSDTC utilizando la herramienta administrativa Servicios de
componentes."

Por lo que entiendo, en este caso lo está tratando como una transacción
distribuida y no local no es asi? y al no tenerlo habilitado desde Servicios
de Componentes, pues larga el error.

En cambio si lo hago de la siguiente manera:


Using TransactionScope
Abrir Conexion

Guardar.Factura
EjecutarComando
Fin Guardar.Factura

GuardarDetalle.Factura
EjecutarComando
Fin GuardarDetalle.Factura

Fin TransactionScope

He utilizado una sola conexion abierta y funciona perfectamente sin
habilitar nada del MS DTC y es aqui donde me pierdo un poco, me puedes
alumbrar y guiarme en como seria esa funcion ComenzarTransaction que deberia
tener en mi capa de Datos? :-)

Muchas Gracias
Guillermo
Respuesta Responder a este mensaje
#3 Alberto Poblacion
30/03/2008 - 21:47 | Informe spam
"Guillermo Peralta" <guillermoperalta(-a.r.r.o.b.a.-)onenet.com.ar> wrote in
message news:
[...]
Porque si por ejemplo tengo:

Using TransactionScope

Guardar.Factura
AbrirConexion
EjecutarComando
CerrarConexion
Fin Guardar.Factura

GuardarDetalle.Factura
AbrirConexion (*) // Aqui
EjecutarComando
CerrarConexion
Fin GuardarDetalle.Factura

Fin TransactionScope


Al Ejecutar de este modo, en el lugar indicado con asterisco, se me
presenta la execpcion "Se ha
deshabilitado el acceso de red para el administrador de transacciones
distribuidas (MSDTC). Habilite DTC para el acceso de red en la
configuración
de seguridad de MSDTC utilizando la herramienta administrativa Servicios
de
componentes."



Efectivamente, al abrir la segunda conexión el TransactionScope ha
intentado "escalar" la conexión pasándola de local a distribuida, y como el
DTS está deshabilitado, da un error.


[...] He utilizado una sola conexion abierta y funciona perfectamente sin
habilitar nada del MS DTC y es aqui donde me pierdo un poco, me puedes
alumbrar y guiarme en como seria esa funcion ComenzarTransaction que
deberia tener en mi capa de Datos? :-)



Te cuento cómo lo hago yo. Esto son ideas mías, y no defiendo que sea la
solución óptima; puede ser que alguien haya inventado algo mejor.
Lo que hago en capa de datos es que tengo una función con un nombre tal
como ObtenerCommand() que me devuelve un SqlCommand ya inicializado con una
conexión abierta a la base de datos del programa, y un LiberarCommand() que
cierra su conexión. Normalmente, y mientras no se están usando
transacciones, las distintas rutinas de capa de datos llaman a
ObtenerCommand, lo usan para leer y grabar datos, y llaman a LiberarCommand.
La rutina ComenzarTransaccion, abre conexión, inicia transacción (con
BeginTransaction) y guarda el objeto Transaction en una variable de clase.
Cuando cualquiera de las rutinas de grabación llama a ObtenerCommand, esta
rutina se encuentra con que ya está creada la transacción, y devuelve
directamente un Command inicializado para utilizar esta transacción. De esta
manera, todo el trabajo realizado por las distintas rutinas de grabación
forma parte de la misma transacción, hasta que se lama a la rutina que hace
el commit o el rollback.
Respuesta Responder a este mensaje
#4 Guillermo Peralta
31/03/2008 - 00:25 | Informe spam
Hola, puede ser que alguien haya inventado algo mejor, pero conocer tu idea
es muy valioso y te agradezco el aporte que nos has hecho, porque entiendo
que esto le puede ayudar a más de a uno.

He logrado solucionar mi problema con tu ayuda empleando una logica similar
a la que planteas en tu mensaje. De hecho es como lo que intentaba hacer sin
el uso de System.Transactions pero no daba con la tecla.

Muchas Gracias!
Saludos
Guillermo
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida