No hay ningún estado de transacción administrado por el aspecto de transacción en el alcance
lt! -Definir administrador de transacciones- gt;
ltbean id = " administrador de transacciones " clase = " org . spring framework . JDBC . fuente de datos . administrador de transacciones de fuente de datos "
nombre de propiedad = " fuente de datos " ref = " fuente de datos "/ gt
lt/bean gt
lt; - Activar el soporte de anotaciones para el control de transacciones - gt;
lttx: annotation-driven transaction manager = "transaction manager"/ gt;
Razón dos: si usa transacciones facetadas AOP, Confirme si la expresión de ejecución de Spring Aop escanea correctamente la interfaz de la capa de servicio o la clase de implementación, como se muestra a continuación:
lt! -Definir estrategia de transacción- gt;
lttx: id de asesoramiento = " consejo de tx " transaction-manager = " administrador de transacciones " gt
lttx: atributo gt
¡es! -Todos los métodos que comienzan con consulta son de solo lectura.
lttx: nombre del método = " consulta * " solo lectura = " verdadero "/ gt
lttx: nombre del método = " get* " solo lectura = " verdadero "/ gt ;
lttx: nombre del método="find* "read-only=" true "/ gt
lttx: nombre del método="select* "read-only=" true; "/ gt ;
lt! - Otros métodos utilizan la estrategia de transacción predeterminada: gt;
lttx: nombre del método = " * " roll back-for = " Throwable "/ gt
lt/tx: atributo gt;
lt/tx: consejo gt;
ltAOP: config gt;
ltAOP: pointcut id = " mi pointcut " expresión = " ejecución (* com. servicio de voz . *. *(..))"/ gt;
lt! - Aplique la estrategia comercial definida a los puntos de ruptura anteriores ->;
ltAOP: asesor consejo-ref = "tx consejo" pointcut-ref = "mi punto de corte"/ gt;
lt/AOP: config gt;
Razón tres: este es el punto más importante.
En la configuración del analizador de vistas xml springmvc, muchas personas
lt! - descripción del controlador - gt;
ltcontext: componente-scan base-package = " com . voavoice . English . controlador "/ gt; - El error de escaneo es el siguiente: gt;
ltcontext: componente-scan base-package = " com . VOA voice . English "/ gt
Por lo tanto, es mejor escanear solo. en la configuración de springmvc Para la clase debajo del controlador, ¡simplemente amplíe el rango de escaneo en la configuración del contexto de Spring!
Razón 4: También puede deberse a que el proxy Spring AOP no admite la invocación de métodos dentro de clase, es decir, el método A llama al método B en el mismo servicio. Los funcionarios de Spring no recomiendan el uso de métodos dentro de las clases para llamarse entre sí. Uno es el objeto proxy y el otro es el objeto de destino, por lo que Spring no puede manejar los asuntos del objeto de destino. Existen muchas soluciones maduras para resolver este problema, como abrir el soporte ThreadLocal del proxy AOP o declarar un objeto autorreferencial en el Servicio para abrir la transacción a través de este objeto autorreferencial (objeto proxy). el proxy implementando el objeto de interfaz BeanPostProcessor.
Por ejemplo: 1. Agregue el archivo de configuración XML.
ltAOP: AspectJ-autoproxy exponen-proxy = " true " / gt! - soporte de estilo de anotación - gt;
ltAOP: config exponen-proxy = "true" gt;lt! --soporte de estilo xml - gt;
2. Clase de implementación empresarial modificada
a() en AService llama a esto b(); modificado a >((un servicio)AOP. contexto. proxy actual()). b();
a() no puede abrir una transacción, pero b() puede abrir una transacción.
Razón 5: antes de la reversión manual, debe declarar que el método es administrado por transacción @ transaccional (reversión para = excepción. clase), y luego la reversión manual puede surtir efecto. La anotación de transacciones equivale a abrir el administrador de transacciones de transacciones. commit(status); entonces,
@ Transactional(revertir para = excepción . class) transactionaspectsupport(). setRollbackOnly();
Razón 6: El método de apertura de una transacción debe declararse como público.
En resumen, esta es la solución más completa. Resolví el problema siguiendo los pasos anteriores.