Pregunta

Quiero saber lo que realmente sucede cuando usted anotar un método con @Transactional? Por supuesto, sé que la primavera se ajustará ese método en una transacción.

Sin embargo, tengo las siguientes dudas:

  1. oí que la primavera crea un clase de proxy ? ¿Puede alguien explicar esto con más profundidad . ¿Qué reside realmente en esa clase de proxy? ¿Qué ocurre con la clase real? Y ¿cómo puedo ver creado clase proxy de primavera
  2. También leí en documentos fuente que:
  

Nota: Dado que este mecanismo está basado en proxies, único método 'externo' llamadas entrantes a través del proxy será interceptada . Esto significa que 'auto-invocación', es decir, un método en el objeto de destino llamando a algún otro método del objeto de destino, no dará lugar a una transacción real en tiempo de ejecución, incluso si el método invocado está marcado con @Transactional!

Fuente: http://static.springsource.org/ primavera / docs / 2.0.x / referencia / transaction.html

¿Por qué sólo las llamadas a métodos externos estarán bajo transacción y no los métodos de auto-invocación?

¿Fue útil?

Solución

Este es un gran tema. El documento de referencia primavera dedica varios capítulos a la misma. Recomiendo la lectura de las de orientado a aspectos de programación y Transacciones , como soporte de transacciones declarativa de primavera AOP utiliza en su fundación.

Pero a un nivel muy alto, Primavera crea proxies para las clases que declaran @Transactional en la propia clase o en los miembros. El proxy es prácticamente invisible en tiempo de ejecución. Proporciona una forma para la primavera para inyectar comportamientos antes, después, o alrededor de llamadas de método en el objeto que se aproxima. gestión de transacciones es sólo un ejemplo de los comportamientos que pueden ser enganchados en. Los controles de seguridad son otra. Y puede proporcionar su propia cuenta, también, para cosas como la tala. Así que cuando usted anotar un método con @Transactional , Primavera crea dinámicamente un proxy que implementa la misma interfaz (s) como la clase que está anotando. Y cuando los clientes hacen llamadas en su objeto, las llamadas son interceptadas y los comportamientos inyectados a través del mecanismo de delegación.

Las transacciones en el trabajo EJB de manera similar, por cierto.

A medida que ha observado, a través de, el mecanismo de delegación sólo funciona cuando entra una llamada de algún objeto externo. Cuando se realiza una llamada interna dentro del objeto, en realidad está haciendo una llamada a través de la " este " de referencia, que no pasa por el proxy. Hay maneras de trabajar alrededor de ese problema, sin embargo. Me explico un enfoque en este mensaje del foro en el que yo uso un BeanFactoryPostProcessor para inyectar una instancia de la representación en clases "auto-referencia" en tiempo de ejecución. Puedo guardar esta referencia a una variable miembro llamada " ". Entonces si necesito realizar llamadas internas que requieren un cambio en la situación de la operación de la rosca, que dirigir la llamada a través del proxy (por ejemplo, " me.someMethod () ".) El mensaje del foro se explica en mas detalle. Tenga en cuenta que el BeanFactoryPostProcessor código sería un poco diferente ahora, a medida que se escribe de nuevo en el plazo 1.x primavera. Pero es de esperar que le da una idea. Tengo una versión actualizada que probablemente podría poner a disposición.

Otros consejos

Cuando la primavera se carga las definiciones de frijol, y se ha configurado para buscar las anotaciones @Transactional, se creará estos objetos proxy alrededor de su frijol real. Estos objetos proxy son instancias de clases que son en tiempo de ejecución generada automáticamente. El comportamiento por defecto de estos objetos proxy cuando se invoca un método es sólo para invocar el mismo método en el frijol "objetivo" (es decir, el bean).

Sin embargo, los proxies pueden también ser suministrados con interceptores, y cuando está presente estos interceptores serán invocadas por el proxy antes de invocar el método de bean de destino. Para los frijoles de destino con anotada @Transactional, Primavera creará un TransactionInterceptor, y pasarlo al objeto proxy generado. Así que cuando se llama al método de código de cliente, que está llamando el método en el objeto proxy, que invoca la primera TransactionInterceptor (que comienza una transacción), que a su vez invoca el método en su bean destino. Cuando la invocación termina, la TransactionInterceptor comete / deshace la transacción. Es transparente para el código de cliente.

En cuanto a la cosa "método externo", si el bean invoca uno de sus propios métodos, entonces no va a ser hacerlo a través del proxy. Recuerde, la primavera envuelve el bean en el proxy, el bean no tiene conocimiento de ello. llamadas sólo desde el "exterior" bean ir a través del proxy.

¿Le ayuda?

Como una persona visual, me gusta para pesar con un diagrama de secuencia del patrón de proxy. Si usted no sabe cómo leer las flechas, leí el primero de esta manera:. Client ejecuta Proxy.method()

  1. El cliente llama a un método en el objetivo de su punto de vista, y está en silencio recibido por el proxy
  2. Si se define un antes aspecto, el proxy lo ejecutará
  3. A continuación, se ejecuta el método real (objetivo)
  4. Después de retorno de y después de lanzamiento de son aspectos opcionales que están ejecutado tras el procedimiento vuelve y / o si el método produce una excepción
  5. Después de eso, el proxy ejecuta el después de aspecto (si se ha definido)
  6. Finalmente el proxy devuelve al cliente llamando

Proxy patrón de secuencia Diagrama (Se me permitió publicar la foto en condiciones que he mencionado sus orígenes Autor:. Noel Vaes, página web: www.noelvaes.eu)

La respuesta más simple es, en el método que se declara @Transactional el límite de transacción comienza y termina límite cuando el método se completa.

Si está utilizando la llamada APP continuación, todos los envíos son con en este límite de transacción. Digamos que usted está ahorrando Entity1, entity2 y entity3. Ahora mientras que el ahorro entity3 una excepción ocurrirá entonces como enitiy1 y entity2 viene en una misma operación de manera Entity1 y entity2 serán rollback con entity3.

Transacción: (entity1.save, entity2.save, entity3.save). Cualquier excepción dará lugar a la reversión de todas las transacciones de la APP con DB. transacción Internamente JPA se utilizan en la primavera.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top