2012-03-07 12 views
6

Estoy usando JAX-RS para proporcionar una interfaz basada en HTTP para administrar un modelo de datos. El modelo de datos se almacena en una base de datos e interactúa a través de JPA.Cómo administrar transacciones con JAX-RS, Spring y JPA

Esto me permite modificar la interfaz del modelo de datos para adaptarme a los clientes de REST y, en general, parece funcionar bastante bien. Sin embargo, no estoy seguro de cómo manejar el escenario en el que un método proporcionado por un recurso JAX-RS requiere una transacción, lo que afecta el patrón de obtención, actualización y compromiso en tx end de JPA, porque solo hay un ajuste de transacción la operación get, por lo que la actualización nunca se confirma. Puedo ver el mismo problema que ocurre si una sola operación REST requiere múltiples operaciones JPA.

Como uso el soporte de transacciones de Spring, lo más obvio es aplicar @Transactional a estos métodos en los recursos de JAX-RS. Sin embargo, para que esto funcione, Spring necesita administrar el ciclo de vida de los recursos de JAX-RS, y los ejemplos de uso de los que tengo conocimiento se crean mediante `nuevo 'cuando es necesario, lo que me pone un poco nervioso de todos modos.

puedo pensar en las siguientes soluciones:

  1. actualizar mis métodos de la APP para proporcionar una versión transacción gestionados de todo lo que quiero hacer de mi interfaz REST atómicamente. Debería funcionar, mantiene las transacciones fuera de la capa JAX-RS, pero evita el patrón get, update, commit-on-tx-end y significa que necesito crear una interfaz JPA muy granular.
  2. Inyectar objetos de recursos; pero son típicamente con estado manteniendo al menos el ID del objeto que interactúa con
  3. Elimine la jerarquía de recursos e inyecte superrecursos grandes y sin estado en la raíz que administra toda la jerarquía desde esa raíz; no grandes servicios cohesivos
  4. Tienen una jerarquía de objetos auxiliares inyectados, sin estado, que admiten transacciones y que 'sombrean' los recursos reales; los recursos son instanciados y mantienen este estado pero delegan invocaciones de métodos a los objetos auxiliares

¿Alguien tiene alguna sugerencia? Es bastante posible que haya perdido algún punto clave en alguna parte.


Actualización - para evitar la falta de una transacción alrededor del GET, actualización, cometió-en-TX-cierre flujo, puedo exponer el método de fusión EntityManager (objeto) y lo llaman de forma manual. No es ordenado y no resuelve el problema más grande sin embargo.


Actualización 2 @skaffman Ejemplo de código: En capa de servicio APP, inyectado, anotaciones trabajan

public class MyEntityJPAService { 
... 
@Transactional(readOnly=true) // do in transaction 
public MyEntity getMyEntity(final String id) { 
    return em.find(MyEntity.class, id); 
} 

En recurso JAX-RS, creado por los nuevos, no hay transacciones

public class MyEntityResource { 
... 
private MyEntityJPAService jpa; 
... 
@Transactional // not injected so not effective 
public void updateMyEntity(final String id, final MyEntityRepresentation rep) { 
    MyEntity entity = jpa.getMyEntity(id); 
    MyEntity.setSomeField(rep.getSomeField()); 
    // no transaction commit, change not saved... 
} 

Respuesta

4

Tengo algunas sugerencias

  1. Introduce una capa entre tus capas JPA y JAX-RS. Esta capa consistiría en beans @Transactional gestionados por Spring, y formaría las diversas operaciones de nivel empresarial a partir de sus llamadas JPA de componentes. Esto es algo similar a su (1), pero mantiene la capa JPA simple.

  2. Reemplazar JAX-RS con Spring-MVC, que proporciona la misma (o similar) funcionalidad, incluyendo @PathVariable, @ResponseBody, etc.

  3. programación envolver su JAX-RS objetos en proxies transaccionales usando TransactionProxyFactorybean. Esto detct sus anotaciones @Transactional y generar un proxy que los honra.

  4. Utilice @Configurable y AspectJ LTW para permitir que Spring cumpla con @Transactional incluso si crea el objeto usando `new. Ver 8.8.1 Using AspectJ to dependency inject domain objects with Spring

+0

¿Están estas sugerencias ordenadas en el orden de preferencia (según usted)? – brainOverflow

Cuestiones relacionadas