G'day, While working with payment processors I came across a dilemma that must have been solved before so here I am. Let's say there's a 3rd party payment processing component (stateless session bean for the sake of this example) that participates in a transaction. This component sends XML messages over HTTP to the bank and the bank replies back in XML. If a method called on the payment bean completes successfully but another method called later in the same transaction fails and throws a system exception, the application has make sure the owner's account balance is not affected. The best way to do this would be to make another call to the payment bean using the amount in the failed transaction but with the opposite sign. In banking, this is usually referred to as a 'reversal adjustment' -- you don't delete an incorrect entry, you merely credit the account and post another entry. (In my hypothetical example above posting another entry is not necessary). This is also a classic example of 'undo' (Command design pattern). Alternatives: 1) Make sure the payment is the last step in the transaction (lame!) 2) Do authorization and settlement separately (ok but more hassle) 3) Delegate the responsibility to operations (if the customer calls about his bill, credit the account manually) The $64,000 question: how do I write an 'undo' in the context of a transaction? I want the entire transaction to fail if the payment bean throws an exception but I also want the application to request an undo if the steps following the payment processing fail. An answer that I am not happy with: use try/catch at the top level (calling component), catch the exception and request an undo. The problem with this approach is that if the payment is encapsulated in the method that activates the service this payment is supposed to be for then interfaces have to be modified to expose the payment details (good: via Command, bad: via a parameter, ugly: directly). Before: ISPCustomer.startService(Service s), ISPMerchant.buyGoods(Goods g), ISPPartner.startRelationship(Contract c) After: ISPCustomer.startService(Service s, Command c) or startService(Service s, boolean undo) or startService(Service s) and undoStartService(Service s) An answer that I want but can't find in the spec (1.1 or 2.0): the component is allowed to register a custom rollback mechanism (factory, Method instance, whatever) with the container that will then be called if the transaction fails. Seems to me this would be a very useful feature...does it not exist in some form? Alex Smith Insight LLC _________________________________________________________________ Get your FREE download of MSN Explorer at http://explorer.msn.com =========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff EJB-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
