Jboss 7.1.1事务,级联EJB方法

时间:2012-06-01 18:11:47

标签: transactions jboss7.x ejb-3.1

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

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

我在weblogic服务器上对此进行了双重检查,该服务器显示了已完成的行为。 我的问题是JBoss为什么不回滚整个交易?我错过了什么......

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

我正在使用jboss 7.1.1,app被部署为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);
            }

        }
    }

...
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

你离开了最重要的部分; JMS连接工厂,您可以从中获取连接以及如何掌握此工厂。

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