2012-06-01 2 views
4

У меня есть два без учета состояния SessionBeans. Мой клиент (приложение JSF2) вызывает метод (saveOrderCompletion) на первом EJB (CompletionFacade), который вызывает другой метод (processRequest) во втором EJB (ContactFacade) для отправки сообщения в очередь через JMS.Jboss 7.1.1 Транзакция, каскадные методы EJB

В конце первого вызванного метода я бросаю RuntimException, чтобы увидеть, как ведет себя JBoss. Это должно выполняться в одной транзакции, поэтому транзакция должна выполнить откат, чтобы в очередь не отправлялось сообщение.

Я дважды проверил это на сервере weblogic, который показывает точное поведение. На мой вопрос почему JBoss не откатывает всю транзакцию? Я что-то пропустил ...

Сущность не сохраняется, но сообщение все равно отправляется в очередь.

Я использую JBoss 7.1.1, приложение развертывается как EAR

Вот мои сессионные компоненты ...

/** 
* Session Bean implementation class CompletionFacade 
*/ 
@Stateless 
public class CompletionFacade implements CompletionFacadeRemote, CompletionFacadeLocal { 


    @PersistenceContext(unitName="my_test") 
    private EntityManager entityManager; 


    @EJB 
    ContactFacadeLocal contactFacade; 

    ..... 

    @Override 
    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public OrderCompletion saveOrderCompletion(OrderCompletion orderCompletion) throws TestBusinessException { 
     try { 

      ...do some stuff on entity 

      //persist to get id 
      entityManager.persist(orderCompletion); 


      //finally send email 
      contactFacade.processRequest(orderCompletion,partner); 

      if (0 == 0) 
       throw new RuntimeException("Test RuntimeException "); 

     } catch (TestGenericException re) { 
      throw new TestBusinessException("Could not print orderCompletion: " ,re); 
     } catch (DocumentException e) { 
      throw new TestBusinessException("Could not print orderCompletion: " ,e); 
     } 

     return orderCompletion; 
    } 
} 

и второй фасад:

@Stateless 
public class ContactFacade implements ContactFacadeRemote, ContactFacadeLocal { 

.... 


    /* 
    * actually create message 
    */ 
    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void processRequest(Object request, SmtpPartner partner) throws TestGenericException { 

     if (logger.isDebugEnabled()) { 
      logger.debug("Starting to process request!"); 
     } 

     QueueConnection connection = null; 
     QueueSession session = null; 

     try { 

     ...lookup queue etc... 

      sender.send(QUEUE, objectMessage); 

     } catch (JMSException e) { 
      logger.error("MS Exception:", e); 
     } catch (NamingException e) { 
      logger.error("Naming exception:", e); 
     } ... 
     } finally { 
      try { 
       session.close(); 
       connection.close(); 
      } catch (JMSException e) { 
       logger.error("Error closing connection:", e); 
      } 

     } 
    } 

... 
} 

Любая помощь высоко ценится.

ответ

3

Вы оставили самую важную часть; фабрику соединений JMS, на которой вы получаете соединение и способ получения этой фабрики.

Убедитесь, что вы ввели эту фабрику и используете транзакционную систему. В JBoss AS 6 java:/JmsXA была транзакционной, а java:/ConnectionFactory - неуправляемой/не-транзакционной альтернативой. Убедитесь, что для AS 7 вы используете правильный.

+0

Спасибо за ваш ответ. Я изменил инъекцию соответственно: @Resource (mappedName = "java:/JmsXA") ' Теперь он работает как исправлено. Большое спасибо! – chrisF

Смежные вопросы