Неожиданное поведение сессионных компонентов с отслеживанием состояния, когда они упакованы во время войны и помещены в ухо.

Я новичок в EJBS. Я написал сессионный компонент с отслеживанием состояния @SessionScoped. Затем я внедрил ejb в свой сервлет.

@Local
@SessionScoped
@Statueful
public class CartServiceImpl implements CartService {

    private int i = 0;

    public int getI() {
        return i++;
    }
}

В моем сервлете

@Inject
private CartService cartService;
.
.
.
out.print(cartService.getI());

Затем я открыл два браузера (IE, FF) и нажал на сервлет. В IE я вижу вывод от 0 до n. В firefox я также вижу вывод, начиная с 0 до n.

Затем я создал ухо, в котором есть сосуд и война. Баночка содержит все файлы EJB. war содержит сервлеты.

Вот как я ввел ejb в сервлет

@Resource(lookup = "java:app/ejb-beginner-ejb/CartServiceImpl")
private CartService cartService; 

Затем я попытался запросить тот же сервлет из IE и FF и получил неожиданный результат.

Результат выглядит следующим образом

В IE я запросил первый раз и получил 0 на выходе. Затем я обновил страницу и на выходе получил 1. Затем я перехожу к FF, отправляю запрос в первый раз и получаю 2 в качестве вывода вместо 0. Затем я перехожу в IE, обновляю страницу и получаю 3 в качестве вывода вместо 2.

Я понял, что сервер приложений создает только один экземпляр ejb с отслеживанием состояния. Как я могу это исправить?

В чем разница между упаковкой ejbs в war и упаковкой их отдельно в jar module?


person Krishna Chaitanya    schedule 31.01.2014    source источник
comment
Интересный. По-видимому, когда вы упаковывали его как часть войны, область действия сеанса буквально означала часть сеанса HTTP, в то время как, когда вы упаковывали его в модуль EJB, это, конечно, больше не связано с каким-либо сеансом HTTP и, по-видимому, управлялось на основе IP-адреса. клиента. Во всяком случае, это то, к чему я пришел из результатов ваших тестов. Фасоль с состоянием для меня загадочная тварь.   -  person Gimby    schedule 31.01.2014
comment
Хорошо. В этом случае, когда истечет срок действия сессионного компонента с отслеживанием состояния? Когда сессионный компонент с сохранением состояния привязан к сеансу http, срок его действия истекает, как только клиент завершает работу (например, закрытие браузера). В случае, если сеанс http не привязан, а компонент сеанса с сохранением состояния использует IP-адрес клиента, когда удалено / прекращено? Это когда клиент меняет свой ip? Это когда клиент перезагружает свою машину?   -  person Krishna Chaitanya    schedule 31.01.2014
comment
Если узнаешь, дай мне знать!   -  person Gimby    schedule 31.01.2014


Ответы (1)


Я думаю, это связано с тем, что аннотация @SessionScoped предназначена для использования только в веб-контексте, иначе, как и в вашем втором случае, это не имеет смысла, и вы должны предполагать, что она будет проигнорирована и ваш ejb с отслеживанием состояния будет вести себя как старый обычный ejb с отслеживанием состояния, и в целом вам не следует вводить ресурсы с сохранением состояния в ресурсы без состояния, поскольку обычно результаты непредсказуемы и зависят от реализации контейнера. При этом сервлеты являются компонентами без сохранения состояния, и спецификация не требует от контейнера создавать один экземпляр для каждого запроса или сеанса из спецификации Servlet 3.0 (раздел 2.2):

Для сервлета, не размещенного в распределенной среде (по умолчанию), контейнер сервлета должен использовать только один экземпляр для каждого объявления сервлета. Однако для сервлета, реализующего интерфейс SingleThreadModel, контейнер сервлета может создавать несколько экземпляров для обработки большой нагрузки запроса и сериализации запросов к конкретному экземпляру.

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

ИЗМЕНИТЬ

Я бы использовал bean-компоненты с привязкой к сеансу в своем веб-приложении, но если вам определенно нужно использовать EJB с отслеживанием состояния (потому что вам нужны некоторые из предоставляемых ими сервисов), то вы могли бы в сервлете искать ejb, когда это необходимо, и связывать его с пользователь HttpSession, чтобы сделать его сеансом, в этом случае вы должны быть осторожны и убедиться, что по истечении сеанса ejb удаляется путем реализации прослушивателей жизненного цикла сеанса, отметьте это

другие последствия следует учитывать здесь

person Camilo    schedule 31.01.2014
comment
Я мало что понял из вашего объяснения. Насколько я понимаю, никогда не следует вводить bean-компонент с сохранением состояния в bean-компонент сервлета / без состояния. Итак, что мне тогда делать, чтобы использовать bean-компоненты с отслеживанием состояния? Должен ли я создавать экземпляр bean-компонента с отслеживанием состояния в методе doGet или doPost сервлета? Я правильно понимаю? - person Krishna Chaitanya; 03.02.2014
comment
Извините, я все еще не могу понять. Не могли бы вы предоставить мне фрагмент кода о том, что вы имеете в виду, просматривая ejb и связываясь с пользователем HttpSession. - person Krishna Chaitanya; 03.02.2014
comment
Я ввел SFSB в свой сервлет, открыл 2 браузера и увидел два разных сеанса. Мой SFSB привязан к сеансу. Он работает нормально. Я использовал jboss для тестирования. - person Krishna Chaitanya; 04.02.2014