2009-03-23 11 views
0

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

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

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

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

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

Спасибо.

ответ

2

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

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

что-то вдоль линий:

public class MyPublicEjb { 
    @EJB 
    private MyPrivateImpl impl; 

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

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

+0

С учетом того, что частному EJB требуется аннотация @TransactionAttribute (TransactionAttributeType.REQUIRES_NEW) (в противном случае мы имеем ту же ситуацию, что и раньше, поскольку транзакция охвачена вызывающим EJB), это сработало. Благодарю. –

0

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

Для (2): Оберните каждый экземпляр с помощью beginTransaction() и commit().

for(each Entity){ 
    try{ 
     //begin transaction 
     //save entity 
     //commit 
    } catch(Exception e) { 
     //handle Exception, but continue on 
    } 
} 
+0

Как я уже сказал, исключение, похоже, выбрасывается из отдельного потока - или, по крайней мере, после того, как мой код завершил то, что он делает. В частности, мой код возвратил управление серверу приложений к моменту исключения исключения - т. Е. Его не удалось поймать. –

+0

Во-вторых, я вполне понимаю общее решение этой проблемы - просто не о том, как это сделать в EJB3. Как начать и совершить транзакции с помощью EntityManager? Как я могу получить EntityManager, который не связан с транзакцией, управляемой контейнером? –

 Смежные вопросы

  • Нет связанных вопросов^_^