Durante el proceso de desarrollo, se encontró un error. La razón del error fue que la transacción de primavera envió mensajes de producción más tarde que la cola de mensajes, lo que resultó en datos incorrectos obtenidos cuando la cola de mensajes consume mensajes. Este artículo presenta la aparición de problemas y el proceso de resolución paso a paso.
1. Problema que surge:
Restauración del escenario: un método en la interfaz, primero modifique el estado del pedido y luego produzca mensajes de la cola de mensajes. El consumidor de la cola de mensajes obtiene el estado de la orden de detección de mensajes y encuentra que el estado del pedido no ha cambiado.
Código:
@Service (OrderApi) Clase pública OrderApiImpl implementa OrderApi {@Resource MQService MQService; @Orderdao Orderdao; public void Push (String OrderId) {// Actualizar el estado del pedido, el estado anterior fue 1 UpdateStatus (OrderId, 3); // Generar el mensaje mqservice.produce (ordenid); } public viod updateTatus (string ordenid, estado entero) {ordendao.updatestatus (ordenid, status); }}El motivo del problema: todos los métodos en OrderAPI tienen transacciones, y el tipo de transacción propagation_required, por lo que la operación del método push en los datos se enviará después de que se ejecute todo el código de empuje. Antes de enviar la transacción, se ha generado el mensaje de la cola de mensajes, por lo que el estado del pedido consumido en la consulta de cola de mensajes de la base de datos puede ser 1. Para hacer que el error sea más obvio, puede agregarlo al final del método de push:
Pruebe {Thread.sleep (10000);} Catch (InterruptedException e) {// TODO BLOQUE DE CABTA AUTODe esta manera, encontrará que el estado del pedido no debe haber sido modificado cuando se consume el mensaje de consumo.
2. Solución al problema:
Solución: al actualizar los datos, cree algo nuevo para asegurarse de que después de ejecutar el código de actualización se ejecute, se ha cometido la transacción que actualiza la base de datos. (Asegúrese de que la operación de la base de datos se haya enviado antes de generar el mensaje)
Según el esquema anterior, lo primero que pienso es modificar directamente el tipo de transacción del método UpdateTatus; Cambié el tipo de transacción de este método a propagation_requires_new (cree una nueva transacción, si la transacción existe actualmente, suspenda la transacción actual).
Pero hay dos cosas inapropiadas que hacer:
1. La modificación forzada del tipo de transacción de UpdateStaus puede afectar otros procesos.
2. No funciona, no se creó una nueva transacción en el método UpdateStaus.
Explicación sobre el segundo punto: Spring agrega transacciones a través de BeannameautoProxyCreator, que solo agrega transacciones a los objetos de frijoles. Ahora llamar métodos dentro de la clase no activará la creación de cosas nuevas.
Entonces, después de probar lo anterior, creé una nueva clase:
@Service ("OrderSextapi") clase pública OrderSextAPIImpl {@Resource OrderApi OrderApi; public void UpdateTatusNeWPagation (String OrderId) {OrderApi.Updatestatus (OrderId); }}y agregue la propagación de la transacción_requires_new para el método de actualización de UpdateTatusNewPropagation
Esta clase es solo para crear una nueva transacción para el método UpdateStaus en OrderAPI.
Ok, hasta ahora el error se ha resuelto.
Sin embargo, todavía hay problemas en el código: la operación de la base de datos se ha enviado, y si hay una excepción en el mensaje de producción, todavía está mal para la lógica de negocios. Por lo tanto, es necesario detectar si la generación de mensajes se completa.
El código en el orden final es el siguiente:
@Service (OrderApi) Clase pública OrderApiImpl implementa OrderApi {@Resource MQService MQService; @Resource Orderdao Orderdao; @Resource OrderSextapiImpl OrderSeTextapi; public void Push (String OrderId) {// Actualizar el estado del pedido, el estado anterior fue 1 OrderSextapi.UpdatestatusNewPropagation (OrderId, 3); // Generar mensajes: Producuce detectará si ocurre una excepción. Cuando se devuelve 1, significa que el mensaje de producción es exitoso. Respuesta de respuesta = MQService.Production (OrderId); if (respuesta.getCode ()! = 1) {log.info ("Mensaje de la cola Excepción de mensajes de producción:" + respuesta.getErrormsg ()) // Excepción de mensajes de producción, restablezca el estado y espere la próxima reexecución Orderextapi.UpdateStatusNewPropagation (OrderId, 1); }} public viod updateTatus (string ordenid, estado entero) {ordendao.updatestatus (ordenid, status); }}Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.