@MessageDriven Transaktionen und Redelivery Semantik

8

Was ist der beste Weg, um das Folgende zu erreichen?

  • @MessageDriven Bean arbeitet an der Datenbank
  • Bei einem Fehler möchte ich die DB-Transaktion zurücksetzen
  • Ich möchte aber auch, dass die JMS-Nachricht NICHT erneut gesendet wird, d. h. nicht erneut versuchen.

Ich kann mir einige Möglichkeiten vorstellen, wie funktionieren könnte . Gibt es noch andere und welche ist die beste?

  • Verwenden Sie @TransactionManagement(type=BEAN) und UserTransaction , und führen Sie nach dem Abfangen der Ausnahme einen expliziten Rollback durch. z.B.:

    catch (Exception e) { e.printStackTrace(); utx.rollback(); }

  • Verwenden Sie containergesteuerte Transaktionen, geben Sie @TransactionAttribute(value=NOT_SUPPORTED) für onMessage an und delegieren Sie dann die DB-Aktivität an eine separate Methode mit @TransactionAttribute(value=REQUIRED) .

  • Behalten Sie die Transaktionsverarbeitung bei und konfigurieren Sie die Wiederholungseigenschaft auf dem Server neu. Ich benutze Glassfish 3.1.1 und bin mir nicht sicher, wie ich das einstellen soll.

  • Lassen Sie alles in Ruhe und überprüfen Sie die Nachricht explizit auf erneute Zustellung im onMessage -Body und beenden Sie sie, wenn sie erneut zugestellt wird. ( message.getJMSRedelivered() ?)

Was hat da draußen gut funktioniert? Gibt es einen Standard / Best-Practice-Weg, um damit umzugehen?

    
wrschneider 31.12.2011, 17:33
quelle

2 Antworten

8

Der einfachste und portabelste Ansatz ist die Verwendung von @TransactionAttribute(value=NOT_SUPPORTED) auf onMessage() , während Sie die DB-Arbeit mit @TransactionAttribute(REQUIRES_NEW)

angeben und in eine andere Bean verschieben

Seien Sie vorsichtig bei der separaten Methode, da dies nicht funktioniert. In einer JMS-MDB ist die onMessage() -Methode die einzige Methode, bei der @TransactionAttribute verwendet werden kann.

    
David Blevins 02.01.2012, 19:00
quelle
2

Persönlich arbeite ich nie in der MDB, sondern spreche sofort zu einer (injizierten) Session-Bean.

Diese Bean funktioniert dann mit der DB. Es startet entweder eine neue Transaktion, oder ich fange irgendeine Ausnahme von der Bean und logge sie ein (aber lass sie nicht propagieren, also keine Neulieferung).

Dies hat auch den Vorteil, dass die Geschäftslogik von anderen Stellen einfach wiederverwendet werden kann.

    
Mike Braun 02.01.2012 09:29
quelle