Подтвердить что ты не робот

EJB-транзакции в локальных методах-вызовах

В следующей настройке работает ли метод B в (новой) транзакции?

EJB, имеющий два метода, метод A и метод B

public class MyEJB implements SessionBean
    public void methodA() {
       doImportantStuff();
       methodB();
       doMoreImportantStuff();
    }

    public void methodB() {
       doDatabaseThing();
    }
}

EJB управляется контейнером с помощью метода B в require_new транзакции и метода A в требуемой транзакции. Таким образом:

<container-transaction id="MethodTransaction_1178709616940">
  <method id="MethodElement_1178709616955">
    <ejb-name>MyName</ejb-name>
    <method-name>*</method-name>
  <trans-attribute>Required</trans-attribute>
  </method>
  <method id="MethodElement_1178709616971">
    <ejb-name>MyName</ejb-name>
    <method-name>methodB</method-name>
  </method>
  <trans-attribute>RequiresNew</trans-attribute>
</container-transaction>

Теперь позвольте другому методу вызова EJB с вызовом метода EJB. methodA теперь выполняется в транзакции. Будет ли последующий вызов методаB из метода A выполняться в той же транзакции или выполняется в новой транзакции? (ум, это фактический код здесь. Нет явного ejb-вызова метода B)

4b9b3361

Ответ 1

Ваш вызов methodB() является обычным вызовом метода, не перехваченным контейнером EJB; во время выполнения контейнер EJB будет вводить proxy, а не экземпляр вашего класса, это то, как он перехватывает вызовы и настраивает перед вызовом вашего метода. Если вы используете this, вы вызываете метод напрямую, а не через прокси. Следовательно, оба метода будут использовать одну и ту же транзакцию, независимо от того, что определено в ejb-jar.xml для вызовов через интерфейсы EJB.

Ответ 2

добавить SessionContext и запросить его для своего прокси-сервера:

@Stateless
public class UserFacade implements UserFacadeLocal {
@Resource
private SessionContext context;

@Override
@TransactionAttribute(TransactionAttributeType.REQUIRED)
private void create(User user) {
        System.out.println("Users Count: "+count()); //invocation#1
        System.out.println("Users Count Through Context: "+context.getBusinessObject(UserFacadeLocal.class).count()); //invocation#2
    }

@Override
@TransactionAttribute(TransactionAttributeType.NEVER)
    public int count() {
        return ((Long) q.getSingleResult()).intValue();
    }
}

в 'invocation # 1' это Локальный вызов, не проходящий через прокси, он вернет счетчик

в 'invocation # 2' это вызов через прокси-сервер, и поэтому вы аннотируете его не поддерживать транзакцию, которая теперь открывается методом create (user), этот вызов вызовет исключение транзакции:

javax.ejb.EJBException: EJB нельзя вызвать в глобальной транзакции

Ответ 3

Они будут использовать ту же транзакцию.

Если я хорошо помню, транзакция запускается контейнером "до", метод вызывается и завершается после его завершения.

Поскольку "a" вызывает "b", "b" будет использовать ту же транзакцию.

: S

Я думаю, самое лучшее, что вы можете сделать, это проверить его, чтобы проверить его!:)