Cómo utilizar UnitOfWork patrón junto con el patrón IdentityMap?

gstackoverflow:

En el libro de Martin Fowler he leído sobre UnitOfWorky IdentityMappatrones.

Autor mencionó que es una buena idea para poner identityMap dentro del UnitOfWork. Pero como hacerlo ?

En lo que entendí IdentityMapestá delimitada por sesión, pero autor no mencioné acercaUnitOfWork

  1. Se UnitOfWorkinstancia limitada por sesión?

  2. Digamos que tenemos entidades clientes y pedidos.

    public clas Client{
    
         List<Order> orders;
        ...
    }
    

y llegamos a la solicitud de información de actualización de clientes (Numeber teléfono) y añadir nuevo orden:

¿Cuántos casos UnitOfWork hacerlo necesidad wee aquí? para cada sesión? deberíamos haber separado los casos para el cliente y para la orden?

¿Cuántos casos IdentityMap qué necesitamos aquí? para cada instancia? deberíamos haber separado los casos para el cliente y para la orden?

¿Cuántos casos IdentityMap qué necesitamos para cada instancia UnitOfWork?

¿Qué pasa si nos dieron 2 solicitudes simultáneas?

Edwin Dalorzo :

Q: ¿Es la UnitOfWorkinstancia limitada por sesión?

En el capítulo 11 del libro de Martin en cuestión se lee:

“Una unidad de trabajo realiza un seguimiento de todo lo que haces durante una transacción comercial que puede afectar a la base de datos. Cuando haya terminado, se da cuenta de todo lo que se necesita hacer para alterar la base de datos como resultado de su trabajo. [...]

“Tan pronto como se empieza a hacer algo que puede afectar a una base de datos, se crea una unidad de trabajo para realizar un seguimiento de los cambios. Cada vez que crear, modificar o borrar un objeto informar a la unidad de trabajo. También puede dejar que se sabe acerca de los objetos que has leído hasta que se pueda comprobar si hay inconsistente lee mediante la verificación de que ninguno de los objetos cambiados en la base de datos durante la transacción comercial “.

Por lo tanto, el UnitOfWorkno tiene que estar vinculado a la sesión. La extensión de la existencia de la UnitOfWorkinstancia depende de su diseño. En el ejemplo de Martin en el mismo libro, podemos ver que se crea la instancia UnitOfOWork por petición HTTP (que creo que es el uso más clásico).

class UnitOfWorkServlet...

   final protected void doGet(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException {
      try {
         UnitOfWork.newCurrent();
         handleGet(request, response);
         UnitOfWork.getCurrent().commit();
      } finally {
         UnitOfWork.setCurrent(null);
      }
   }

   abstract void handleGet(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException; 

En la especificación JPA, la unidad de trabajo puede ser de dos naturalezas distintas: contexto de persistencia con ámbito de transacción, un contexto de persistencia extendido, pero también se puede manejar manualmente y obtener una unidad de aplicación gestionados de trabajo ( ver esta otra respuesta ) . La que utilice depende del caso de uso.

Q: ¿Cuántos casos IdentityMap necesitamos?

Martin Fowler también responde a esta pregunta en el libro. En su sección sobre la IdentityMapque hay una sección completa al respecto.

El libro se lee:

“Aquí la decisión varía entre un mapa por cada clase y un mapa para toda la sesión."

Donde se podía comprender la sesión como UnitOfWorken este caso. Más adelante en el libro, explica:

“Si tiene varios mapas, la ruta obvia es un mapa por clase o por mesa, que funciona bien si sus modelos de esquema de base de datos y objetos son los mismos.

Unos párrafos más adelante Martin explica dónde poner el IdentityMap:

“Identidad mapas deben estar en un lugar donde son fáciles de encontrar. También están ligados al contexto de proceso que se está trabajando. Usted necesita asegurarse de que cada sesión recibe su propia instancia que está aislado de la instancia de cualquier otra sesión. Por lo tanto, es necesario poner la identidad de mapa en un objeto de sesión específica. Si está utilizando unidad de trabajo que es, con mucho, el mejor lugar para los mapas de identidad desde la unidad de trabajo es el lugar principal para hacer el seguimiento de los datos que vienen dentro o fuera de la base de datos. Si usted no tiene una unidad de trabajo, la mejor apuesta es un registro que está ligada a la sesión “.

Así que, ahí lo tienes, si tu UnitOfWorkestá obligado a una petición, entonces tendrá uno o más IdentityMapsde esa instancia de su UnitOfWork.

Por lo tanto, es la unidad de trabajo delimitada por transacción de negocios?

Sí lo es.

Ahora bien, el alcance de la "transacción comercial" podría ser de corta duración, por ejemplo ligado a la vida de la petición HTTP como en el ejemplo de Martin Fowler por encima de donde la UnitOfWork parece estar ligado a una variable local de subprocesos por solicitud.

O la "transacción comercial" podría abarcar múltiples peticiones, por ejemplo, en JPA hay un concepto de un contexto de persistencia prolongada, cuando el contexto persistente en la APP corresponde a un UnitOfWorkpatrón. En un contexto de persistencia prolongada, la transacción comercial se extiende por un período de tiempo más largo. Un ejemplo clásico de esto es un carrito de la compra: cuando el usuario comienza a poner artículos en su cesta de la compra se crea un contexto / unidad de trabajo, y el contexto no ser anulado hasta que el usuario comprueba hacia fuera su cesta de la compra (la comisión de los cambios) o su sesión expira (descartando todo en la unidad de trabajo).

Ahora, también existe la idea de contexto de aplicación gestionados, que básicamente significa, comienzan su unidad de trabajo cuando se piensa que es apropiado y lo cierra cuando ya no lo necesite. Por ejemplo, suponga que tiene una aplicación de escritorio y una pequeña base de datos con la concurrencia aislado (es decir, cada usuario sólo maneja sus propios datos y no afecte a datos de otros usuarios). Supongamos que los datos del usuario podrían encajar perfectamente en la memoria del ordenador. En un caso así, usted podría comenzar su UnitOfWorken el inicio de la aplicación y usarlo como una especie de caché para su base de datos. Cuando sea apropiado, se puede lavar el UnitOfWork en el disco, por ejemplo, cuando el usuario hace clic en un botón de guardar, pero aún así mantenerlo vivo. Cuando el usuario cierra la aplicación, el UnitOfWork se descarta.

Por lo tanto, se puede ver que hay una gran cantidad de matices de lo que una "transacción comercial" significa en realidad, o por el tiempo que el UnitOfWorkdebería existir.

Varias unidades de trabajo

Sobre la base de la explicación hasta el momento, se pueden tener varias unidades de trabajo para, entre otras, las siguientes razones:

  • Uno UnitWorkpor solicitud, y si su aplicación se encarga de solicitudes simultáneas, entonces tendría múltiples unidades de instancias de trabajo al mismo tiempo.
  • Uno UnitOfWorkpor transacción extendida, y por lo tanto, vinculados a la sesión del usuario. Si tiene varios usuarios, puede tener varias unidades de trabajo.

Sin embargo, además de estos, he encontrado otras razones por las que usted puede querer generar una nueva unidad de trabajo durante el mismo "transacción comercial".

No es raro que mientras se está ejecutando una transacción comercial es posible que desee ejecutar otra totalmente independiente. Por ejemplo, supongamos que a fin de realizar un pedido de cliente, el registro de cliente debe existir en la base de datos, pero si el registro del cliente deja de ser creado (por ejemplo, tal vez porque otro cliente tiene mismo correo electrónico en conflicto), todavía se desea colocar el orden en el estado pendiente de revisión.

Por lo tanto, el problema que se enfrenta es que si se intenta crear el cliente durante la transacción del negocio de hacer un pedido y crear el cliente no, que contamina su transacción pedido y su unidad de trabajo se ve obligado a volver rollo de todo. En una situación como esta es posible que desee generar una nueva unidad de trabajo y, por tanto, una nueva, transacción de base de datos independiente, para crear el cliente y si esa unidad de trabajo independiente no puede crear el cliente, esto no contaminar su unidad de creación de la orden de trabajo, que le permite tomar medidas para aún persisten su pedido sin un cliente en un estado de espera de revisión.

Creo que el concepto de un "contexto" de la APP es un muy buen ejemplo de cómo definir una unidad de trabajo. Yo sugeriría que se estudia su especificación en particular su sección sobre el EntityManager.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=312413&siteId=1
Recomendado
Clasificación