4

2つのステートレスSessionBeanがあります。私のクライアント(JSF2アプリケーション)は、最初のEJB(CompletionFacade)でメソッド(saveOrderCompletion)を呼び出しています。このメソッドは、2番目のEJB(ContactFacade)で別のメソッド(processRequest)を呼び出して、JMSを介してキューにメッセージを送信します。

最初に呼び出されたメソッドの最後に、JBossがどのように動作するかを確認するためにRuntimExceptionをスローします。これはすべて1つのトランザクションで実行する必要があるため、トランザクションはロールバックを実行して、メッセージがキューに送信されないようにする必要があります。

これを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;
    }
}

と2番目のファサード:

@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がアンマネージド/非トランザクション型の代替手段でした。AS7の場合は正しいものを使用していることを確認してください。

于 2012-06-02T19:27:25.447 に答える