EJB3 - обработка исключений RollBackExceptions

У меня есть приложение EJB3, которое состоит из некоторых EJB для доступа к БД и предоставляется через Session Bean в качестве веб-службы.

Теперь мне нужно выяснить две вещи:

1) Есть ли способ остановить исключения SQL, которые заставят веб-службу генерировать ошибку SOAP? Транзакции обрабатываются контейнером, и в настоящее время исключения sql вызывают выброс RollBackException и, следовательно, откат транзакции (желаемое поведение) и выдачу ошибки веб-службой (нежелательно).

2) Я хочу расширить веб-сервис, чтобы иметь возможность принимать список сущностей, а сессионный компонент - сохранять каждую. Однако я хочу, чтобы каждая сущность выполнялась в отдельной транзакции, чтобы в случае сбоя одной из них не пострадали другие (и снова веб-служба не должна отказывать).

Для (1) я попытался перехватить RollBackException, но я предполагаю, что это выброшено где-то в другом потоке, поскольку блок перехвата никогда не достигается. Я предполагаю, что для (2) мне нужно будет изучить пользовательские транзакции, но, во-первых, я бы предпочел, чтобы контейнер управлял этим, а во-вторых, я не знаю, как принудительно использовать пользовательские транзакции.

Спасибо.


person Anthony Roy    schedule 23.03.2009    source источник


Ответы (2)


нет, вы можете сделать все это с помощью транзакций, управляемых контейнером (и это определенно предпочтительнее, поскольку управление транзакциями - это боль).

суть решения состоит в том, чтобы создать второй EJB только с локальным интерфейсом и желаемой семантикой транзакции. тогда ваш «общедоступный» ejb, который веб-служба вызывает напрямую, вызывает этот второй ejb через свой локальный интерфейс для выполнения фактической работы.

что-то вроде:

public class MyPublicEjb {
  @EJB
  private MyPrivateImpl impl;

  public void doSomething() {
    try {
      impl.doSomething();
    } catch(TXRolledBack) {
      // handle rollback ...
    }
  }
}

Я знаю, что это выглядит некрасиво, но поверьте мне, это намного предпочтительнее прямого управления транзакциями.

person james    schedule 23.03.2009
comment
С оговоркой, что частный EJB требует аннотации @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW) (в противном случае мы имеем ту же ситуацию, что и раньше, поскольку транзакция ограничена вызывающим EJB), это сработало. Спасибо. - person Anthony Roy; 24.03.2009

Для (1): выполните отладку кода, чтобы узнать, где возникает исключение и что его вызывает. Затем обработайте исключение там.

Для (2): заключите каждый экземпляр в beginTransaction () и commit ().

for(each Entity){
    try{
        //begin transaction
        //save entity
        //commit
    } catch(Exception e) {
         //handle Exception, but continue on
    }
}
person Kevin Crowell    schedule 23.03.2009
comment
Как я уже сказал, исключение, похоже, было выброшено из отдельного потока - или, по крайней мере, после того, как мой код завершил то, что он делает. В частности, мой код вернул управление серверу приложений к моменту возникновения исключения, то есть его невозможно поймать. - person Anthony Roy; 23.03.2009
comment
По второму пункту я хорошо осведомлен об общем решении такого рода проблем, а не о том, как это сделать в EJB3. Как начать и зафиксировать транзакции с помощью EntityManager? Как мне получить EntityManager, который не привязан к транзакции, управляемой контейнером? - person Anthony Roy; 23.03.2009