Was ist der beste Weg, um das Folgende zu erreichen?
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?
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)
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.
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.
Tags und Links jms glassfish-3 glassfish ejb-3.1 message-driven-bean