2010-09-02 12 views
8

Es posible (incluso probable) que simplemente no esté asimilando por completo el concepto de una "unidad de trabajo". Básicamente, lo veo como una especie de transacción amplia utilizada en un entorno orientado a objetos. Comience la unidad de trabajo, interactúe con los objetos, comprométase o retráigase. Pero, ¿cómo se relaciona esto con las transacciones reales en los almacenes de datos detrás de esos objetos?Unidad de trabajo con múltiples fuentes de datos?

En un sistema con una única base de datos y un ORM (como NHibernate) es fácil. La transacción se puede mantener a través del ORM. Pero, ¿qué ocurre con un sistema en el que los modelos de dominio personalizado ocultan muchas fuentes de datos dispares? Y no todas esas fuentes de datos son bases de datos relacionales? (Aquí se hace mucho en el sistema de archivos.)

En este momento estoy atascado en la idea de que "simplemente no se puede mantener una transacción en una base de datos SQL2005, una base de datos SQL2000, un DB de DB2 y el sistema de archivos todo en la misma operación comercial 'atómica'. " Por lo tanto, por ahora, es responsabilidad de los desarrolladores del equipo (que generalmente trabajan de forma independiente el uno del otro) mantener las transacciones manualmente en el código. Cada DB puede tener transacciones apropiadas en él, pero la operación del negocio como un todo se verifica manualmente y se balancea en cada paso significativo del camino.

Sin embargo, con la complejidad cada vez mayor en el dominio y la rotación del desarrollador estándar, este enfoque será cada vez más difícil y propenso a errores en el tiempo.

¿Alguien tiene algún consejo o ejemplos de cómo un dominio como este podría ser mejor abordado, o cómo se ha abordado antes? El "dominio" real en este caso todavía está en su infancia, evolucionando como un prototipo para expandir y consumir/reemplazar un gran ecosistema de aplicaciones legacy dispares. Así que hay mucho espacio para rediseñar y volver a factorizar.

Como referencia, una vista de 10,000 pies del diseño al que estoy apuntando actualmente es: una gran colección de pequeñas aplicaciones de cliente tan tontas como sea posible que llamen a un servicio central basado en mensajes. El servicio es la entrada al "núcleo del dominio" y puede considerarse como una gran aplicación de estilo MVC. Las solicitudes se hacen al servicio (al igual que las "acciones") que son recogidas por los controladores (al igual que los "controladores"). Todo lo procesal va allí. Interactúan con los modelos, que contienen todas las reglas comerciales. Los modelos publican eventos que los oyentes ("servicios", esta parte aún está nublada en el diseño y sujeto a mejoras) recogen y manejan mediante la interacción con repositorios (base de datos x, base de datos, sistema de archivos, correo electrónico, cualquier recurso externo). Todo alegremente, inyectado en dependencia en consecuencia.

Perdón por toda la verborrea :) Pero si alguien tiene algún consejo, me encantaría escucharlo. Incluso (especialmente) si ese consejo es "su diseño es malo, intente esto en su lugar ..." ¡Gracias!

+1

¿Has consultado alguna vez al Coordinador de transacciones distribuidas? http://msdn.microsoft.com/en-us/library/ms684146(VS.85).aspx –

+0

@Michael: he tenido suerte al utilizar TransactionScope/MSDTC con soluciones SqlServer. Atravesar el sistema de archivos y otros RDBMS puede ser más complicado. OP está hablando de coordinar el trabajo sobre varios motores de base de datos así que es por eso que no estoy sugiriendo MSDTC como una respuesta. –

Respuesta

9

Anteriormente trabajé en un sistema que podía lograr esto, y es bastante sencillo. Dado que su proyecto está en sus primeras etapas, tal vez esta podría ser información útil para usted. Lamentablemente, ya no tengo acceso al código, pero aún me siento cómodo al describir cómo funcionó.

Lo que hice fue crear mis repositorios usando una implementación de patrón de repositorio genérico. El tipo de repositorio base siempre será referenciado por los servicios y UoW. En aras de la discusión, lo llamaremos BaseRepository. "T" estaría restringido a las implementaciones de IEntity, que denotaba un objeto de dominio. Desde BaseRepository, había creado otro conjunto de clases base para la composición, como SqlBaseRepository, XmlBaseRepository, etc.

A la UoW solo le preocupa que algo sea del tipo BaseRepository, que es donde existiría la funcionalidad principal. Se representaría CUD básico (de CRUD), proporcionando los equivalentes para Crea, Actualizaciones y Eliminaciones.Lo que haría cada uno de ellos sería crear un delegado y colocarlo en una cola dentro de la UoW, también transmitiendo información sobre qué tipo de transacción iba a ser y los datos apropiados necesarios para completarla. La UoW comenzaría a mantener una lista de los repositorios que necesitarían estar involucrados en la transacción, pero todavía no le importaba qué tipo era. Eficazmente, hacer cola aquí es como alistarse en una transacción.

El BaseRepository definió un método abstracto llamado algo así como .ApplyChange(). Una vez que se llamó a .Commit() en la UoW, crearía un TransactionScope() y comenzaría a llamar a los delagates en la lista, devolviendo la información a .ApplyChange(). La implementación real de .ApplyChange() existe en la base de repositorio específico, es decir, SqlRepositoryBase, etc., y también puede ser anulada por la implementación.

Donde se puso complicado, para mí al menos, estaba retrocediendo. Solo traté con una única base de datos, pero a veces tenía cambios basados ​​en archivos que se realizaron. Agregué un método .RevertChange() y comencé a rastrear el estado original y los estados modificados para poder aplicar un delta inverso para volver a donde estaba en la pila de archivos.

Ojalá pudiera ser más específico en la implementación, pero ha pasado más de un año desde la última vez que he visto el código. Puedo decirles que la base del código original proviene del libro, .NET Domain-Driven Design with C#: Problem - Design - Solution, de Tim McCarthy. Una gran parte de la implementación de mi repositorio se basó en sus ejemplos, con una gran mayoría de mi personalización en las UoW y su implementación.

Espero que ayude, de alguna manera! :-)

+0

Eso es muy útil, en realidad. Para ser honesto, creo que la recomendación del libro será la más útil a largo plazo. Tal vez es hora de que reduzca el ritmo de los retoques y me ponga al día con la lectura. Probablemente esté en el punto de mi carrera en que ese libro y los libros en los que el autor lo basó (específicamente el libro de Fowler, que he postergado por algún tiempo) serán una buena base para seguir adelante. ¡Gracias! – David

+1

No hay problema, David. Ese libro también tiene un proyecto en CodePlex, que olvidé mencionar. Al menos puede tirar hacia abajo la fuente y patear los neumáticos. ;-) http://dddpds.codeplex.com/ –

Cuestiones relacionadas