Während des Entwicklungsprozesses wurde ein Fehler aufgetreten. Der Grund für den Fehler war, dass die Spring Transaction Produktionsmeldungen später als die Meldungswarteschlange übermittelt hat, was zu falschen Daten führte, die bei der Verbrauchsmeldungsmeldungen erhalten wurden. In diesem Artikel wird die Entstehung von Problemen und den Schritt-für-Schritt-Auflösungsprozess eingeführt.
1. Problem entstehen:
Szenario -Wiederherstellung: Eine Methode in der Schnittstelle, zuerst den Bestellstatus ändern und dann Nachrichten aus der Nachrichtenwarteschlange erstellen. Der Verbraucher der Nachrichtenwarteschlange erhält den Status zur Auftragsbeschaffung der Nachrichtenerkennung und stellt fest, dass sich der Bestellstatus nicht geändert hat.
Code:
@Service (orderAPI) öffentliche Klasse OrderApiimpl implementiert OrderAPI {@resource mqService mqservice; @Orderdao orderdao; public void push (string orderId) {// Aktualisieren des Bestellstatus, der vorherige Status war 1 UpdateStatus (orderid, 3); // generieren Sie die Nachricht mqService.produce (orderId); } public viod updateStatus (String orderId, Ganzzahlstatus) {OrderDao.UpDatestatus (orderId, Status); }}Der Grund für das Problem: Alle Methoden in der Ordnung von ordnungsgemäßen haben Transaktionen, und der Transaktionstyp Propagation_Requeed. Daher wird der Betrieb der Push -Methode auf den Daten eingereicht, nachdem der Push -Code ausgeführt wird. Bevor die Transaktion übermittelt wird, wurde die Meldung der Nachrichtenwarteschlange generiert, sodass der Status der in der Meldungswarteschlange aus der Datenbank verbrauchten Reihenfolge 1 sein kann. Um den Fehler offensichtlicher zu machen, können Sie ihn am Ende der Push -Methode hinzufügen:
try {thread.sleep (10000);} catch (InterruptedException e) {// Todo automatisch generierter Catch-Block e.printstacktrace ();}Auf diese Weise werden Sie feststellen, dass der Bestellstatus nicht geändert worden sein muss, wenn die Verbrauchsnachricht verbraucht wird.
2. Lösung für das Problem:
Lösung: Erstellen Sie beim Aktualisieren von Daten eine neue Sache, um sicherzustellen, dass nach Ausführung des Update -Code die Transaktion, die die Datenbank aktualisiert, begangen wurde. (Stellen Sie sicher, dass die Datenbankoperation vor der Erstellung der Nachricht eingereicht wurde.)
Nach dem obigen Schema denke ich als erstes, den Transaktionstyp der UpdateStatus -Methode direkt zu ändern. Ich habe den Transaktionstyp dieser Methode in Propagation_requires_New geändert (erstellen Sie eine neue Transaktion, wenn die Transaktion derzeit vorhanden ist, die aktuelle Transaktion aussetzen).
Aber es gibt zwei unangemessene Dinge zu tun:
1. Erzwungene Änderung des Updatestaus -Transaktionstyps kann andere Prozesse beeinflussen.
2. Nicht funktionieren, wurde in der Updatestaus -Methode keine neue Transaktion erstellt.
Erläuterung zum zweiten Punkt: Spring fügt Transaktionen über BeannameAutoproxycreator hinzu, was nur Transaktionen zu Bean -Objekten hinzufügt. Wenn Sie nun Methoden innerhalb der Klasse aufrufen, wird die Erstellung neuer Dinge nicht ausgelöst.
Nachdem ich das oben genannte ausprobiert hatte, habe ich eine neue Klasse erstellt:
@Service ("orderextapi") public class orderextapiimpl {@resource orderapi orderapi; public void updatestatusNewPropagation (String orderId) {orderAPI.UpDATESTATUS (orderId); }}und Transaktionsrepagation addieren
Diese Klasse soll nur eine neue Transaktion für die Updatestaus -Methode in Orderapi erstellen.
OK, bisher wurde der Fehler behoben.
Es gibt jedoch immer noch Probleme im Code: Der Betrieb der Datenbank wurde eingereicht, und wenn die Produktionsnachricht eine Ausnahme gibt, ist es für die Geschäftslogik immer noch falsch. Daher ist es notwendig zu erkennen, ob die Nachrichtenerzeugung abgeschlossen ist.
Der Code im endgültigen Orderapi lautet wie folgt:
@Service (orderAPI) öffentliche Klasse OrderApiimpl implementiert OrderAPI {@resource mqService mqservice; @Resource orderdao orderdao; @Resource orderextapiimpl orderextapi; public void push (string orderId) {// Aktualisieren des Bestellstatus, der vorherige Status war 1 orderextapi.UpDatestatusNewPropagation (orderid, 3); // Meldung erzeugen --Produkten erkennen, ob eine Ausnahme auftritt. Wenn 1 zurückgegeben wird, bedeutet dies, dass die Produktionsnachricht erfolgreich ist. Antwort Antwort = MQService.Produce (orderId); if (response.getCode ()! }} public viod updateStatus (String orderId, Integer Status) {OrderDaO.UpDatESTATUS (orderId, Status); }}Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.