services create spring grails service transactions transactional

spring - services - grails create service



Algunas preguntas sobre el servicio de Grails (2)

Deberías hacer una pregunta por pregunta :)

Para la pregunta n. ° 1, sí, la integración de Spring / Hibernate garantiza que se realice una descarga antes de la confirmación. Por lo tanto, las llamadas a save() y delete() se delete() y no es necesario agregar flush: true a ninguna de las dos. Además, las instancias sucias que no haya llamado a save() también se eliminarán a menos que llame a discard() .

Para el n. ° 2: los servicios son transaccionales por defecto, por lo que transactional = true es realmente redundante; solo necesita especificarlo para decir transactional = false . Pero el contenedor automático de transacciones que se crea solo se realiza si no hay anotaciones @Transactional . Si tiene una o más anotaciones, entonces esas definen la demarcación de la transacción. Por lo tanto, de forma predeterminada (es decir, sin anotaciones y sin propiedad transactional o transactional = true ) todos los métodos son transaccionales, pero si solo se anota un subconjunto de los métodos, solo aquellos serán transaccionales.

Normalmente, utilizaría anotaciones cuando desee un comportamiento no predeterminado, es decir, propagación personalizada, aislamiento, tiempo de espera, etc. (o haga que sea de solo lectura como en su ejemplo).

Puede anotar en el nivel de clase para tener la misma configuración para todos los métodos y, opcionalmente, anotar métodos individuales para anular los valores predeterminados de ámbito de clase.

Para # 3 y # 4, se aplican las reglas estándar (ver # 2). Si la subclase tiene anotaciones, entonces transactional = true de esa clase o una clase principal se ignoraría ya que al usar las anotaciones le dices a Grails que tú mismo estás configurando las cosas.

Dado que los servicios abstractos no se pueden instanciar, la subclase concreta que se instancia realmente tendrá un comportamiento combinado de la clase base y de sí mismo. Si todo es transactional = true entonces es simple, y si tiene anotaciones, entonces definen las reglas.

Los métodos de llamada en la superclase se comportarían igual que los métodos de llamada en la clase actual. Pero el comportamiento es un poco contra-intuitivo si no has considerado las implicaciones del enfoque de proxy de Spring. Cuando llama a un método transaccional, el proxy intercepta la llamada y se une a la transacción activa, o inicia una nueva si es necesario, o inicia una nueva si se especifica REQUIRES_NEW. Pero una vez que esté en la clase real y llame a otro método, omitirá el proxy. Entonces, si llamas a otro método con diferentes configuraciones de anotación, serán ignoradas. Si va a hacer eso, consulte esta discusión de la lista de correo electrónico para ver lo que está sucediendo y cómo trabajar con él: http://grails.1312388.n4.nabble.com/non-transactional-service-extends-transactional-service -outcome-td3619420.html

Estoy trabajando con una aplicación web de Grails y recibo tantas cosas extrañas cuando uso el servicio Grails. Así que quiero hacer algunas preguntas sobre esto para que entienda más acerca de los servicios de Grails. Esto será muy útil para mí (y tal vez para otros ^ _ ^). Gracias por adelantado.

  1. Si un servicio se configura con static transactional = true, ¿va a vaciar todos los cambios de datos a DB después de invocar cualquier método con un objeto que está sucio y bloqueado en la sesión de Hibernate?

  2. ¿Puedo usar la anotación @Transactional en el nivel de clase en lugar de static transactional = true ? ¿Y es posible poner @Transactional(readOnly = true) en algunos métodos que solo quiero que lean (consulten, encuentren) datos de DB?

  3. ¿Qué tal la herencia de transacción? Quiero decir que, si el servicio padre se configura static transactional = true , y el servicio hijo tiene su propia anotación @Transactional (en la clase) y algo de @Transactional(readOnly = true) (en algunos métodos), ¿qué pasará si llamo? un método en el padre del niño uno?

  4. ¿Funciona la transacción con un servicio abstracto? Porque, como sé, con el servicio abstracto no podemos inicializar su bean, y quizás al iniciar la aplicación, hay algunas diferencias en el contexto de Grails.


Y otra pregunta:
En el servicio principal, puse @Transaction en el nivel de clase, pero en el servicio secundario, simplemente puse @Transactional(readOnly=true) en un método (es decir, doChild() ), no en la clase. Cuando llamo a doChild() desde el servicio secundario, todavía va a lavar los datos. No sé la razón por la cual el servicio para niños ignora la configuración de transacción específica que puse en ese método.