2010-11-13 17 views
23

Para entender el funcionamiento de las transacciones de Spring, quiero saber qué sucede en el siguiente caso en el que un método marcado como @Transactional llama a otro método marcado como @Transactional.Comprensión de las transacciones de Spring: ¿qué sucede cuando un método transaccional llama a otro método transaccional?

Supongamos que la configuración utiliza todas las configuraciones predeterminadas.

@Service("myService") 
@Transactional 
public MyService{ 
    public void myServiceMethod(){ 
     myDAO.getSomeDBObjects(); 
    } 
} 

@Repository("myDAO") 
@Transactional 
public MyDAOWithUsesBeyondMyService{ 
    public void getSomeDBObjects(){...} 
} 

Ahora bien, si tuviera que entrar en MyService.myServiceMethod() sería empezar con claridad una transacción. Luego, al perforar en myDAO.getSomeDBObjects(), ¿qué pasaría? ¿El hecho de que una transacción ya exista no hace que nazca una nueva transacción, o estoy creando dos transacciones aquí?

La documentación (citada a continuación) sobre Propagación parece cubrir esto, pero me gustaría verificar mi comprensión, era un poco para mi cerebro virgen comprender todo de una vez.

Propagación: Típicamente, todo el código ejecutado dentro de un ámbito de transacción se ejecutará en esa transacción. Sin embargo, tiene la opción de especificar el comportamiento en caso de que se ejecute un método transaccional cuando ya existe un contexto de transacción. Por ejemplo, el código puede continuar ejecutando en la transacción existente (el caso común ); o puede suspenderse la transacción existente y crearse una nueva transacción . Spring ofrece todas las de las opciones de propagación de transacciones conocidas de EJB CMT. Para leer acerca de la semántica de la transacción de propagación en Spring, consulte la Sección 10.5.7, "Propagación de transacción".

Respuesta

33

dos respuestas:

a) no lo hacen. Utilice @Transactional en la capa de servicio o la capa DAO, pero no ambos (la capa de servicio es la opción habitual, ya que es probable que desee una transacción por método de servicio)

b) si lo hace, lo que sucede depende de la propagation atributo de la anotación @Transactional y se describe en esta sección: 10.5.7 Transaction propagation. Básicamente: PROPAGATION_REQUIRED significa que se usará la misma transacción para ambos métodos, mientras que PROPAGATION_REQUIRES_NEW inicia una nueva transacción.

Acerca de sus comentarios:

Por supuesto que seguí leyendo y se dio cuenta de que, como yo estoy usando proxies, este segundo método no será gestionado por el proxy transaccional, así como cualquier otro llamada de método

No es cierto en su caso (solo si ambos métodos pertenecen a la misma clase).

Si un grano tiene métodos a y b, y a llamadas b, entonces b se llama en el método real, no el proxy, ya que se llama desde dentro del proxy (un grano no sabe que se aproxima al mundo exterior).

proxy  bean 
a() --> a() 
      | 
      V 
b() --> b() 

En su situación, sin embargo, un servicio tendría un objeto DAO inyectada, lo que sería un proxy en sí, por lo que tendría una situación como esta:

  proxy  bean 
service a() --> a() 
         | 
      /---------/ 
      |     
      V 
dao  b() --> b() 
+0

Gracias, sí, no tengo la intención de hacer esto, pero la pregunta me vino a la mente cuando me di cuenta de que había declarado @Transactional en un nivel de clase de servicio, y un método del servicio llamaba a otro método del servicio (ambos transaccionales). Por supuesto seguí leyendo y me di cuenta de que, como estoy usando proxys, este segundo método no será administrado por el proxy transaccional, por lo que es como cualquier otra llamada a método (eso es suficiente para confundir un cerebro recién iniciado). :) Pero me hizo lo suficientemente curioso como para asegurarme de haber entendido los detalles de cómo funciona todo, me lo has aclarado bien. ¡Gracias! –

+0

@David Creo que malinterpretaste un poco el concepto de proxy. Lee mi actualización –

+0

Tiene toda la razón, mi comentario fue un error (en realidad cambié las suposiciones sin decirlo), pero entiendo lo que está diciendo, y después de todo eso, creo que todo está bien enraizado en mi cabeza ahora. Gracias por la actualización y los excelentes diagramas, estoy seguro de que muchos otros lo encontrarán útil en sus búsquedas en el futuro. –

Cuestiones relacionadas