== AbortParticipant Imagine you have a list of participants that define a transaction, for example: * +ValidateMessage+ (sanity checks) * +FetchData+ (i.e. get Terminal/Merchant info from database) * +QueryRemoteHost+ * +LogTransaction+ * +SendResponse+ If everything goes okay and all participants return +PREPARED+, then you'll have no problem reaching the last set of participants. By contrast, if for some reason a given participant fails (e.g., imagine +FetchData+ fails), then the remaining participants down the list (in our example, FetchData through +SendResponse+) won't get called because the transaction manager will initiate the aborting procedure (which will call abort(id,context) only on the previously-called participants, i.e., only on ValidateMessage in our example). In the previous example, while it's okay to ignore a call to the +QueryRemoteHost+ participant, you may still want to send a response back to the client, or even log the transaction, so you do want to call +SendResponse+. The link:http://jpos.org/doc/javadoc/org/jpos/transaction/AbortParticipant.html[AbortParticipant] is designed to solve this problem: [source,java] ------------- public interface AbortParticipant extends TransactionParticipant { public int prepareForAbort (long id, Serializable context); } ------------- Participants implementing the +AbortParticipant+ will get called even if the transaction is bound to abort. [TIP] ===== If we use this technique to implement a +SendResponse+ participant, as an additional protection it is a good idea to verify that we are not approving a transaction. ===== [NOTE] ====== As of jPOS 2.1.0 the `prepareForAbort` has a default implementation that calls the TransactionParticipant's `prepare` method. ====== If you see the previous diagram, when participant 3 returns `ABORTED`, the last participant doesn't get called. If participant number four implements this `AbortParticipant` interface, the diagram would look like this: image:images/tm_abort_participant.png[width="400px",alt="AbortParticipant"] At `prepareForAbort()` time, returning `PREPARED`, or `ABORTED`, is quite the same. A `PREPARED` wouldn’t affect the flow of the transaction, it’s still in its `ABORT` track. But the `NO_JOIN` modifier could be useful if you’re doing nothing in your `abort()` callback. It’s an indication to the TM that it doesn’t need to call abort. The difference is minimal, calling a dummy `abort()` method that does nothing is quite fast, but the TM still needs to register that it needs to call that participant, and it records histograms, profiler, etc. So `NO_JOIN` is a good thing to consider returning.