EJB 3.1 – Lidando com exceções em jobs assícronos

Eu tenho vários trabalhos asynchronouss que eu gostaria de lidar com a exceção de maneira transparente. Eu gostaria de colocar a lógica de tratamento de exceção em outro componente / class. Com o Seam 2, eu estendi uma class manipuladora de exceção.

Por exemplo, eu gostaria de criar um evento com a exceção dele, para que eu possa ter vários componentes agindo como quiserem. O mais comum é aquele que notifica os administradores.

Obrigado,

Walter

Aqui está um exemplo da Parte Três: Novos Recursos no EJB 3.1 que você provavelmente pode adaptar:

Invocação assíncrona de beans de session

O processamento asynchronous é um requisito surpreendentemente comum para muitos aplicativos corporativos. Alguns dos casos de uso mais óbvios estão acionando processos em segundo plano acionados por ignorar e esquecer, manipulando tarefas de longa execução, mantendo a interface do usuário receptiva ou simplesmente aumentando o rendimento do aplicativo, utilizando os benefícios do parallel processing. A maneira mais fácil de implementar o processamento asynchronous em aplicativos Java EE hoje é usar o Message Driven Beans. Na verdade, o primeiro exemplo de Message Driven Bean no EJB 3 em Action é usado para implementar o faturamento de pedidos asynchronous. Mais precisamente, um Message Driven Bean ( OrderBillingMDB ) fatura de forma assíncrona o cliente depois que o pedido é confirmado e atualiza as informações do pedido com os resultados da tentativa de faturamento depois de concluído. A figura 1 mostra este cenário:

texto alternativo

Figura 1: Faturamento asynchronous de pedidos

Embora o uso do Message Driven Beans para processamento asynchronous certamente funcione, ele também força você a lidar com mensagens e JMS, mesmo para funcionalidades relativamente leves. Esse é precisamente o problema que a chamada do bean de session assíncrona foi projetada para resolver. Com esse aprimoramento, você pode fazer o processamento asynchronous simplesmente anotando um método de bean de session com a anotação @Asynchronous . Vamos dar uma olhada no EJB 3 re-fatorado no exemplo Action para faturamento asynchronous usando o recurso:

 @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); } } ... } 

Por causa da anotação @Asynchronous , quando o cliente chama o método OrderBillingService.billOrder , a chamada retornará imediatamente em vez de bloquear até que o método billOrder termine a execução. O contêiner EJB irá certificar-se de que o método seja executado de forma assíncrona (provavelmente usando mensagens sob o capô). Como você pode ver, o tipo de retorno do método asynchronous é nulo. Esse provavelmente será o caso de uma grande maioria dos methods de bean de session assíncrona. No entanto, o EJB 3.1 também pode suportar um tipo de retorno de java.util.concurrent.Future , em que V representa o valor resultante de uma chamada assíncrona. Caso você não esteja familiarizado com isso, a interface Future permite fazer coisas como cancelar uma chamada assíncrona, verificar se uma chamada está concluída, verificar exceções e obter os resultados de uma chamada assíncrona. Confira a documentação da interface Future aqui: http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html . Vamos dar uma olhada rápida em um exemplo usando o tipo de retorno Futuro. No método billOrder , no exemplo anterior, definimos o status do pedido de acordo com o resultado da tentativa de faturamento e atualizamos o pedido. Vamos supor que o invocador atualize o pedido e queira saber qual era o status da tentativa de cobrança. Poderíamos fazer isso refatorando o método billOrder seguinte maneira:

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

O object javax.ejb.AsyncResult é uma implementação conveniente da interface Future . Leva o resultado da invocação assíncrona como um argumento de construtor. Não há nada que impeça você de usar sua própria implementação do Future . A chamada assíncrona suporta alguns outros resources interessantes, como garantias de entrega e semântica de envio transacionado. Para detalhes, confira o rascunho da especificação.

Se você tiver um problema específico, faça uma pergunta mais específica 🙂

Veja também

  • EJB 3.1 – Um Passo Significativo para a Maturidade
  • A interface do Future