La pregunta no es privada ni pública, la pregunta es: ¿cómo se invoca y qué implementación de AOP utiliza?
Si usa Spring Proxy AOP de Spring (predeterminado), toda la funcionalidad de AOP proporcionada por Spring (like @Transational
) solo se tendrá en cuenta si la llamada pasa por el proxy. - Este suele ser el caso si el método anotado se invoca desde otro bean.
Esto tiene dos implicaciones:
- Como los métodos privados no deben invocarse desde otro bean (la excepción es la reflexión), su
@Transactional
Anotación no se tiene en cuenta.
- Si el método es público, pero se invoca desde el mismo bean, tampoco se tendrá en cuenta (esta declaración solo es correcta si se usa Spring Proxy AOP (predeterminado)).
@Ver Spring Reference: Capítulo 9.6 9.6 Mecanismos de representación
En mi humilde opinión, debe utilizar el modo aspectoJ, en lugar de los Spring Proxies, que resolverá el problema. Y los Aspectos transaccionales de AspectJ se entrelazan incluso en métodos privados (verificado para Spring 3.0).
La respuesta a su pregunta es no: no
@Transactional
tendrá ningún efecto si se utiliza para anotar métodos privados. El generador proxy los ignorará.Esto está documentado en Spring Manual, capítulo 10.5.6 :
fuente
Por defecto, el
@Transactional
atributo solo funciona cuando se llama a un método anotado en una referencia obtenida de applicationContext.Esto abrirá una transacción:
Esto no:
Referencia de Spring: Uso de @Transactional
fuente
Sí, es posible usar @Transactional en métodos privados, pero como otros han mencionado, esto no funcionará de inmediato. Necesitas usar AspectJ. Me tomó un tiempo descubrir cómo hacerlo funcionar. Compartiré mis resultados.
Elegí usar el tejido en tiempo de compilación en lugar del tejido en tiempo de carga porque creo que es una mejor opción en general. Además, estoy usando Java 8, por lo que es posible que deba ajustar algunos parámetros.
Primero, agregue la dependencia para Aspectjrt.
Luego agregue el complemento AspectJ para hacer el tejido de código de bytes real en Maven (esto puede no ser un ejemplo mínimo).
Finalmente agregue esto a su clase de configuración
Ahora debería poder usar @Transactional en métodos privados.
Una advertencia para este enfoque: necesitará configurar su IDE para conocer AspectJ; de lo contrario, si ejecuta la aplicación a través de Eclipse, por ejemplo, puede que no funcione. Asegúrate de probar contra una construcción directa de Maven como un control de cordura.
fuente
Si necesita ajustar un método privado dentro de una transacción y no desea usar Aspectj, puede usar TransactionTemplate .
fuente
TransactionTemplate
uso, pero llame a ese segundo método en..RequiresTransaction
lugar de..InTransaction
. Siempre nombre las cosas como le gustaría leerlas un año después. También diría que si realmente requiere un segundo método privado: poner su contenido directamente en laexecute
implementación anónima o si eso se vuelve desordenado, podría ser una indicación para dividir la implementación en otro servicio que luego puede anotar@Transactional
.Spring Docs explican que
Otra forma es el usuario BeanSelfAware
fuente
BeanSelfAware
? No parece una clase de primaveraLa respuesta es no. Consulte la Referencia de Spring: Uso de @Transactional :
fuente
De la misma manera que @loonis sugirió usar TransactionTemplate, uno puede usar este componente auxiliar (Kotlin):
Uso:
No sé si
TransactionTemplate
reutilizar la transacción existente o no, pero este código definitivamente lo hace.fuente