2

I'm using XA (2-phase) transaction. I want to log to one log-table through Log class and Entity Manager. My method inside EJB Session bean looks like:

private void logError(Throwable throwable) {
    LogEntity logEntity = new LogEntity();
    // Set everything
    entityManager.persist(logEntity);
}

I want to it in isolated (autonomous) transaction independent of any "outer" transaction. I have already tried to add @TransactionAttribute(value = TransactionAttributeType.REQUIRES_NEW) and @TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED) before method name and does not work.

Before I call EJB3 method I create user transaction like:

try {
    UserTransaction transaction = (UserTransaction)context.lookup("javax.transaction.UserTransaction");
    transaction.begin();
    // Call EJB3 method
    transaction.commit();
} catch (Throwable t) {
    t.printStackTrace();
    try {
        transaction.rollback();
    } catch (SystemException e) {
        e.printStackTrace();
    }
}

I want to Log no matter if commit is done or not. How to?

Regards

4

1 回答 1

0

事务属性仅在通过代理调用时才相关。它们不适用于直接调用,其中包括私有方法。尝试以下类似的操作(它使用 EJB 3.1 无接口视图,但如果您只有 EJB 3.0,您可以创建一个单独的本地接口用于日志记录):

@Stateless
@Local(BusinessInterface.class)
@LocalBean
public class MyBean {
  @EJB MyBean logger;

  @TransactionAttribute(REQUIRED)
  public void businessMethod() {
    try {
      ...
    } catch (Throwable t) {
      logger.logError(t);
      ...
    }
  }

  @TransactionAttribute(NOT_SUPPORTED)
  public void logError(Throwable t) {
    ...
  }
}

重要的一点是对 logError 的调用是通过注入的 EJB 代理发生的,它允许容器控制在logError方法期间暂停 XA 事务。

于 2012-05-23T16:31:52.833 回答