Red de conocimiento informático - Problemas con los teléfonos móviles - Los recursos de Spring 4.0 no entran en vigor

Los recursos de Spring 4.0 no entran en vigor

La transacción no surte efecto 1. Problemas de permisos de acceso Como todos sabemos, hay cuatro permisos de acceso principales en Java: privado, predeterminado, protegido y público, y sus permisos aumentan de izquierda a derecha. Pero si tenemos algunos métodos de transacción con derechos de acceso incorrectos definidos durante el proceso de desarrollo, causará problemas con la función de transacción.

} Podemos ver que los derechos de acceso del método agregar están definidos como privados. Esto hará que la transacción falle. Spring requiere que el método proxy sea público. Para decirlo sin rodeos, hay un juicio en el método ComputeTransactionAttribute de la clase AbstractFallbackTransactionAttributeSource, es decir, si el método de destino no es público, TransactionAttribute devuelve nulo, es decir, las transacciones no son compatibles. Es decir, si personalizamos el método de transacción (es decir, el método de destino), que no es público, pero el acceso es privado, predeterminado o protegido, entonces Spring no proporcionará la funcionalidad de transacción.

2. Métodos modificados por final A veces, si no quieres que las subclases reutilicen un método, puedes definirlo como final. Esto no es un problema para los métodos normales, pero si define el método de transacción como final,

} podemos ver que el método add está definido como final, lo que hará que la transacción falle. ¿Por qué sucede esto? Si ha leído el código fuente de las transacciones Spring, es posible que sepa que las transacciones Spring subyacentes utilizan aop, es decir, a través del proxy dinámico jdk o cglib, para ayudarnos a generar clases de proxy e implementar funciones de transacción en las clases de proxy. Pero si un método se modifica a final, entonces en su clase de proxy, el método no se puede anular ni agregar funcionalidad de transacción. Nota: Si un método es estático, no puede convertirlo en transaccional mediante servidores proxy dinámicos.

3. Llamada a método interno A veces necesitamos llamar a otro método de transacción en el método de la clase de servicio.

}Vemos que en el método de transacción agregar, el método de transacción updateStatus es. llamado directamente. Esto se debe a que Spring Aop genera un proxy para el objeto, pero el método llama directamente al método del objeto, por lo que el método updateStatus no genera una transacción. Se puede ver que llamar directamente a métodos de la misma clase internamente hará que la transacción falle. Entonces la pregunta es, ¿qué debemos hacer si realmente necesitamos llamar a otro método en la misma clase bajo ciertas circunstancias? 3.1 Agregar un nuevo método de Servicio Este método es muy simple. Simplemente agregue un nuevo método de Servicio, agregue la anotación @Transactional en el nuevo método de Servicio y luego mueva el código que la transacción debe ejecutar al nuevo método. El código es el siguiente: @Servcie

public class ServiceA

}Algunas personas pueden preguntarse si este enfoque causará problemas de dependencia circular. La respuesta es: no. De hecho, el caché interno de tercer nivel de Spring IOC puede garantizar que no habrá problemas de dependencia circular. Pero también existen algunos peligros ocultos. Si desea saber más sobre los problemas de dependencia circular, puede consultar mi artículo anterior "Spring: ¿Cómo resolver los problemas de dependencia circular?" .3.3 Utilice AopContext.currentProxy() en la clase de servicio para obtener el objeto proxy a través de la clase AopContent. El método 2 anterior resuelve el problema, pero el código no parece intuitivo. También puede obtener el objeto proxy utilizando AOPProxy. la clase de servicio logra la misma funcionalidad.

}4. En nuestro proceso de desarrollo habitual, hay un detalle que fácilmente se pasa por alto y que no está dentro del alcance de la gestión de Spring. Es decir, el requisito previo para utilizar transacciones Spring es que para que Spring administre los objetos, se debe crear una instancia de bean.

Por lo general, podemos implementar automáticamente funciones de instanciación de Bean e inyección de dependencia a través de las anotaciones @Controller, @Service, @Component y @Repository. Por supuesto, hay muchas formas de crear instancias de Bean. Los amigos interesados ​​pueden leer mi artículo anterior "¿Conoce estas interesantes operaciones de @Autowired?". Si un día desarrolla una clase de Servicio rápidamente pero se olvida de agregar la anotación @Service, en el ejemplo anterior podemos ver que el método de transacción doOtherThing se llama en el método de transacción agregar, pero el método de transacción doOtherThing se llama en otro hilo. Esto da como resultado que los dos métodos no estén en el mismo subproceso y obtengan conexiones de bases de datos diferentes, lo que da como resultado dos transacciones diferentes. Si desea que el método doOtherThing genere una excepción, no es posible revertir el método add al mismo tiempo. Si ha leído el código fuente de las transacciones de Spring, sabrá que las transacciones de Spring se implementan a través de conexiones de bases de datos. El hilo actual contiene un mapa donde las claves son fuentes de datos y los valores son conexiones de bases de datos. private static final ThreadLocal> resources =

new NamedThreadLocal("Recursos transaccionales"); Cuando decimos la misma transacción, en realidad nos referimos a la misma conexión de base de datos. Solo con la misma conexión de base de datos podemos confirmar y revertir simultáneamente. . Si están en hilos diferentes, las conexiones a la base de datos obtenidas deben ser diferentes, por lo que son transacciones diferentes. 6. La tabla no admite transacciones. Como todos sabemos, antes de mysql5, el motor de base de datos predeterminado era myisam. No hace falta decir sus ventajas: los archivos de índice y los archivos de datos se almacenan por separado y el rendimiento es mejor que el de innodb para operaciones de una sola tabla que requieren más verificación y menos escritura. Es posible que algunos proyectos antiguos todavía lo utilicen. Al crear una tabla, simplemente configure el parámetro ENGINE en MyISAM: CREATE TABLE `category` ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_binmyisam es fácil de usar, pero hay un problema fatal: no se admiten transacciones. Si se trata de una sola operación de tabla, no es un gran problema. Pero si necesita operar en varias tablas, es probable que los datos estén incompletos porque no se admiten transacciones. Además, myisam no admite bloqueos de fila ni claves externas. Por lo tanto, en escenarios comerciales reales, la tasa de uso de myisam no es alta. Después de mysql5, myisam se retiró gradualmente del escenario de la historia y fue reemplazado por innodb. A veces, durante el proceso de desarrollo, encontramos que la transacción de una determinada tabla no tiene ningún efecto. No es necesariamente el problema de la transacción de primavera. Es mejor confirmar primero si la tabla que está utilizando admite transacciones. 7. No abrir la transacción A veces, la causa raíz de que la transacción no surta efecto es que la transacción no se abre. Cuando veas esta frase, puede que te resulte graciosa. ¿No es abrir una transacción la función más básica de un proyecto? ¿Por qué no abrir una transacción? Sí, si el proyecto ya está construido, la función de transacción debe estar disponible. Pero si está creando una demostración de proyecto y solo hay una tabla, las transacciones de esta tabla no tendrán efecto. Entonces, ¿qué causa esto? Por supuesto, hay muchas razones, pero la razón por la que no se activa la función de transacción se pasa por alto fácilmente. Si estás utilizando el proyecto springboot, estás de suerte. Porque Springboot ha habilitado transacciones silenciosamente a través de la clase DataSourceTransactionManagerAutoConfiguration. Todo lo que tienes que hacer es configurar el parámetro spring.datasource. Sin embargo, si todavía está utilizando un proyecto Spring tradicional, debe configurar manualmente los parámetros relacionados con las transacciones en el archivo applicationContext.xml. Si olvida configurarlo, la transacción definitivamente no tendrá efecto.