Thread.sleep () в EJB - PullRequest
       1

Thread.sleep () в EJB

19 голосов
/ 20 ноября 2011

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

Как лучше всего это реализовать?

Ответы [ 3 ]

13 голосов
/ 20 ноября 2011

EJB 3.1 принес новую @Asynchronous функцию , которой вы можете воспользоваться:

@Asynchronous
@TransactionAttribute(NOT_SUPPORTED)
public Future<WebServiceResult> callWebService(int retries) {
    WebServiceResult result = webService.call();

    if (!result.equals(BUSY)) {
        return result;
    }

    if (retries <= 0) {
        throw new TooBusyException();
    }

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }

    return callWebService(retries - 1);
}

Затем просто позвоните вам через веб-службу:

Future<WebServiceResult> result = yourEJB.callWebService(1);

// Can do some interesting stuff here.
// ...
// ...

result.get(2, SECONDS);  // Block for up to 2 seconds.

Как видите, вы получаете настраиваемое количество повторных попыток и время ожидания бесплатно.

Чем это отличается от простого вызова Thread.sleep()?Возвращение Future является более явным и управляемым.Также я не думаю, что Thread.sleep() это вредно.Единственная проблема заключается в том, что этот экземпляр EJB теперь может больше использоваться другими клиентами.С Future асинхронный вызов происходит внутри некоторого другого EJB и пула потоков.Что касается важности Thread#interrupt() внутри блока catch, обратитесь к Зачем вызывать Thread.currentThread.interrupt () при перехвате любого исключения InterruptException?

Другая идея: использовать аспект вокруг вызова веб-службы, catchBusyException один раз и повторите попытку.

11 голосов
/ 20 ноября 2011

В FAQ по ограничениям EJB конкретно указано, что вы

не должны создавать или управлять потоками

И перевод потока в спящий режимкак «управление».

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

0 голосов
/ 11 августа 2015

Но внешний веб-сервис является внешним, и вы открываете к нему сетевое соединение, и вы хотите заняться управлением.Для этого и нужен JCA, а не EJB.

...