EJB 3.1 - 在异步作业中处理异常 [英] EJB 3.1 - Handling exceptions in asychronous jobs

查看:150
本文介绍了EJB 3.1 - 在异步作业中处理异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个异步作业,我想透明地处理异常。我想将异常处理逻辑放在另一个组件/类中。使用Seam 2,我扩展了一个异常处理程序类。



例如,我想提出一个异常的事件,以便我可以有几个组件在它们看起来合适的时候。最常见的是通知管理员。



谢谢,



Walter

解决方案

以下是

  • 未来< V> 接口


  • I have several asynchronous jobs that I would like to transparently handle the exception for. I'd like to put the exception handling logic in another component / class. With Seam 2, I extended an exception handler class.

    For instance, I'd like to raise an event with the exception in it so that I can have several components act on it as they see fit. The most common one is one that notifies administrators.

    Thanks,

    Walter

    解决方案

    Here is an example from Part Three: New Features in EJB 3.1 that you can probably adapt:

    Asynchronous Invocation of Session Beans

    Asynchronous processing is a surprisingly common requirement for many enterprise applications. Some of the most obvious use cases are triggering fire-and-forget background processes, handling long-running tasks while keeping the user interface receptive or simply increasing application throughput by utilizing the benefits of parallel processing. The easiest way of implementing asynchronous processing in Java EE applications today is using Message Driven Beans. In fact, the first Message Driven Bean example in EJB 3 in Action is used to implement asynchronous order billing. More precisely, a Message Driven Bean (OrderBillingMDB) asynchronously bills the customer after the order is confirmed and updates the order information with the results of the billing attempt once it is completed. Figure 1 shows this scenario:

    Figure 1: Asynchronous order billing

    While using Message Driven Beans for asynchronous processing certainly works, it also forces you to deal with messaging and JMS, even for relatively lightweight functionality. This is precisely the problem asynchronous session bean invocation is designed to solve. With this enhancement, you can do asynchronous processing simply by annotating a session bean method with the @Asynchronous annotation. Let's take a look at the re-factored EJB 3 in Action example for asynchronous billing using the feature:

    @Stateless
    public class OrderBillingServiceBean implements OrderBillingService {
        ...
    
        @Asynchronous
        public void billOrder(Order order) {
            try {
                // Attempt to charge the order.
                bill(order);
                // Send email notification of billing success.
                notifyBillingSuccess(order);
                order.setStatus(OrderStatus.COMPLETE);
            } catch (BillingException be) {
                // Send email notification of billing failure.
                notifyBillingFailure(be, order);
                order.setStatus(OrderStatus.BILLING_FAILED);
            } finally {
                update(order);
            }
        }
    
        ...
    }
    

    Because of the @Asynchronous annotation, when the client invokes the OrderBillingService.billOrder method, the call will return immediately instead of blocking until the billOrder method finishes executing. The EJB container will make sure the method gets executed asynchronously (probably using messaging under the hood). As you can see, the return type of the asynchronous method is void. This will probably be the case for a vast majority of asynchronous Session bean methods. However, EJB 3.1 can also support a return type of java.util.concurrent.Future<V>, where V represents the resultant value of an asynchronous invocation. In case you are unfamiliar with it, the Future<V> interface allows you to do things like cancelling an asynchronous invocation, checking if an invocation is complete, check for exceptions and getting the results of an asynchronous invocation. Check out the documentation for the Future<V> interface here: http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html. Let's take a quick look at an example using the Future return type. In the billOrder method in the previous example, we set the status of the order according to the outcome of the billing attempt and updated the order. Let's assume that the invoker updates the order themselves and wants to know what the status of the billing attempt was. We could do this by refactoring the billOrder method as follows:

    @Stateless
    public class OrderBillingServiceBean implements OrderBillingService {
        ...
    
        @Asynchronous
        public Future<OrderStatus> billOrder(Order order) {
            try {
                // Attempt to charge the order.
                bill(order);
                // Send email notification of billing success.
                notifyBillingSuccess(order);
                return new AsyncResult<OrderStatus>(OrderStatus.COMPLETE);
            } catch (BillingException be) {
                // Send email notification of billing failure.
                notifyBillingFailure(be, order);
                return new AsyncResult<OrderStatus>
                    (OrderStatus.BILLING_FAILED);
            }
        }
    
        ...
    }
    

    The javax.ejb.AsyncResult<V> object is a convenience implementation of the Future<V> interface. It takes the result of the asynchronous invocation as a constructor argument. There's nothing stopping you from using your own implementation of Future<V> however. Asynchronous invocation supports a few other neat features like delivery guarantees and transacted send semantics. For details, check out the spec draft.

    If you have a specific problem, please ask a more specific question :)

    See also

    这篇关于EJB 3.1 - 在异步作业中处理异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆