4

我有两个无状态的 SessionBean。我的客户端(JSF2 应用程序)正在第一个 EJB (CompletionFacade) 上调用方法 (saveOrderCompletion),该方法在第二个 EJB (ContactFacade) 上调用另一个方法 (processRequest) 以通过 JMS 向队列发送消息。

在第一个调用方法结束时,我抛出了一个 RuntimException 来查看 JBoss 的行为。这应该全部在一个事务中运行,因此事务应该进行回滚,这样就不应该将消息发送到队列。

我在 weblogic 服务器上仔细检查了这个,它准确地显示了预期的行为。我的问题是为什么 JBoss 不回滚整个事务?我错过了什么...

实体没有被持久化,但无论如何都会将消息发送到队列。

我正在使用 jboss 7.1.1,应用程序部署为 EAR

这是我的会话 bean...

/**
* 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);
            }

        }
    }

...
}

非常感谢任何帮助。

4

1 回答 1

3

你漏掉了最重要的部分;您从中获取连接的 JMS 连接工厂以及获取该工厂的方式。

确保你注入了这个工厂,并且你使用了一个事务性的。在 JBoss AS 6 中,java:/JmsXA 是事务性的,而 java:/ConnectionFactory 是非托管/非事务性的替代方案。检查您是否使用了正确的 AS 7。

于 2012-06-02T19:27:25.447 回答