Во время процесса разработки возникла ошибка. Причиной этой ошибки было то, что пружинная транзакция, представленная производственными сообщениями позже, чем очередь сообщений, что привело к неверным данным, полученным, когда очередь сообщений потребляет сообщения. В этой статье представлены возникновение проблем и пошаговый процесс разрешения.
1. возникает проблема:
Восстановление сценариев: метод в интерфейсе, сначала изменить состояние заказа, а затем создать сообщения из очереди сообщений. Потребитель очереди сообщений получает статус порядка обнаружения сообщений и обнаруживает, что статус порядка не изменился.
Код:
@Service (orderapi) открытый класс orderapiimpl реализует orderapi {@resource mqservice mqservice; @Orderdao orderdao; public void push (string orderid) {// Обновление статуса заказа, предыдущий статус был 1 updateStatus (OrderId, 3); // генерировать сообщение mqservice.produce (orderid); } public viod updateStatus (String OrderId, Integer Status) {OrderDao.updateStatus (OrderId, Status); }}Причина проблемы: все методы в порядке имеют транзакции, и тип транзакции opragation_required, поэтому операция метода Push на данных будет представлена после выполнения всего Push -кода. Прежде чем отправиться в транзакцию, было сгенерировано сообщение в очереди сообщения, поэтому статус заказа, потребляемого в запросе очереди сообщений из базы данных, может быть 1. Чтобы сделать ошибку более очевидной, вы можете добавить ее в конце метода push:
try {thread.sleep (10000);} catch (прерывание Extexception e) {// todo Auto Generated Catch Block e.printstackTrace ();}Таким образом, вы обнаружите, что статус заказа не должен быть изменен при использовании сообщения о потреблении.
2. Решение проблемы:
Решение: При обновлении данных создайте новую вещь, чтобы убедиться, что после выполнения кода обновления была совершена транзакция, которая обновляет базу данных. (Убедитесь, что операция базы данных была представлена до создания сообщения)
Согласно вышеуказанной схеме, первое, о чем я думаю, это напрямую изменять тип транзакции метода UpdateStatus; Я изменил тип транзакции этого метода на Propagation_Requires_New (создайте новую транзакцию, если транзакция в настоящее время существует, приостановка текущей транзакции).
Но есть две неуместные вещи:
1. Принудительная модификация типа транзакции обновления может повлиять на другие процессы.
2. Не работая, в методе UpdateStaus не было создано никакой новой транзакции.
Объяснение о второй точке: Spring добавляет транзакции через Beannameautoproxycreator, который добавляет только транзакции к объектам бобов. Теперь вызов методов внутри класса не вызовет создание новых вещей.
Итак, после попытки вышесказанного я создал новый класс:
@Service ("ordrextapi") открытый класс orderextapiimpl {@resource orderapi orderapi; public void updateStatusNewPopagation (String orderId) {orderapi.updatestatus (orderid); }}и добавить транзакцию Propagation_Requires_new для метода UpdateStatusNewPropagation
Этот класс просто для создания новой транзакции для метода UpdateStaus in eryasapi.
Хорошо, пока ошибка была решена.
Тем не менее, в коде все еще есть проблемы: операция базы данных была представлена, и если в производственном сообщении есть исключение, это все еще неверно для бизнес -логики. Следовательно, необходимо определить, завершена ли генерация сообщений.
Код в последнем orderapi выглядит следующим образом:
@Service (orderapi) открытый класс orderapiimpl реализует orderapi {@resource mqservice mqservice; @Resource orderdao orderdao; @Resource ordrextapiimpl ordreextapi; public void push (String OrderId) {// Обновление статуса заказа, предыдущий статус был 1 orderextApi.updateStatusNewPopagation (OrderId, 3); // Сгенерировать сообщение -Продукция обнаружит, происходит ли исключение. Когда 1 возвращается, это означает, что производственное сообщение успешно. Ответ ответа = mqservice.produce (orderid); if (response.getCode ()! = 1) {log.info ("Исключение производственного сообщения Сообщения:" + response.getErrormsg ()) // Исключение производственного сообщения, сбросить состояние и ждать следующего повторного выполнения orderextApi.updateStatusNewPopagation (OrderId, 1); }} public viod updateStatus (string orderid, integer status) {orderdao.updatestatus (orderid, status); }}Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.