powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / WebService, EJB, JMS сообщение застревает в транзакции
20 сообщений из 20, страница 1 из 1
WebService, EJB, JMS сообщение застревает в транзакции
    #38309465
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Такая вот проблема. Есть веб сервис, один из методов которого должен отправлять сообщения в очередь JMS. На другом компьютере развернуто приложение смотрит на эту очередь и отвечает на сообщения.
Веб-сервис:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
@Stateless()
@WebService(serviceName = "Dev-test")
public class MessageSender {
    
    // BEGIN // JMS Block //
    
    @Resource(lookup = "ConnectionFactory")
    private ConnectionFactory connectionFactory;
    
    @Resource(lookup = "ServerQueue")
    private Destination serverQueue;
    
    Connection connection = null;
    
//    @PostConstruct
//    public void makeConnection() {
//        try {
//            connection = connectionFactory.createConnection();
//        } catch (Throwable t) {
//        }
//    }
//
//    @PreDestroy
//    public void endConnection() throws RuntimeException {
//        if (connection != null) {
//            try {
//                connection.close();
//            } catch (Exception e) {
//            }
//        }
//    }
    
    private String sendMessage(String message, String messageType) {
        String response = null;
        try {
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer requestProducer = (MessageProducer) session.createProducer(serverQueue);
            TemporaryQueue replyQueue = session.createTemporaryQueue();
            MessageConsumer replyConsumer = session.createConsumer(replyQueue);
            
            connection.start();
        
            // Create message for sending
            TextMessage textMessage = session.createTextMessage();
            textMessage.setJMSType(messageType);
            textMessage.setText(message);
            textMessage.setJMSReplyTo(replyQueue);
            
            requestProducer.send(textMessage);
            
            Message messageFromReplyQueue = replyConsumer.receive();
            TextMessage textMessageFromReplyQueue = (TextMessage) messageFromReplyQueue;
            response = textMessageFromReplyQueue.getText();
        } catch (JMSException ex) { 
            
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (Exception e) {
            }
        }
        return response;
    }
}



Приложение на другой машине:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@MessageDriven(mappedName = "ServerQueue")
public class SAMMessageConsumer implements MessageListener {
    @Resource(name = "ConnectionFactory")
    private ConnectionFactory connectionFactory;

    @Override
    public void onMessage(Message message) {
        //....
    }
}



Все бы хорошо, но все сообщения, отправленные из веб-сервиса попадают в "Held in Transaction" если верить браузеру очередей под названием QBrowser_light_V2.5.2.8.1_forJDK1.6 (см. атач).

Попробовал проделать все тоже самое, только на месте веб-сервиса развернул страницу JSP и сервлет. Вот код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
@WebServlet(name = "MessageSender", urlPatterns = {"/MessageSender"})
public class MessageSender extends HttpServlet implements MessageListener {
    
    private Session session;
    private MessageProducer requestProducer;
    private MessageConsumer replyConsumer;
    
    @Resource(name = "ConnectionFactory")
    private ConnectionFactory connectionFactory;
    
    @Resource(name = "ServerQueue")
    private Destination serverQueue;
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String log = this.sendMessage(request.getParameter("message"));
        PrintWriter printWriter = response.getWriter();
        printWriter.print(log);
        printWriter.flush();
    }
    
    private String sendMessage (String message) {
        Connection connection = null;
        try {            
            connection = connectionFactory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            
            requestProducer = (MessageProducer) session.createProducer(serverQueue);
                        
            TemporaryQueue replyQueue = session.createTemporaryQueue();
            replyConsumer = session.createConsumer(replyQueue);
            
            connection.start();
            
            // Create message for sending
            TextMessage textMessage = session.createTextMessage();
            textMessage.setJMSType(MessageType.GET_KEYS.toString());
            textMessage.setText(message);
            textMessage.setJMSReplyTo(replyQueue);
            
            requestProducer.send(textMessage);
                        
            Message messageFromReplyQueue = replyConsumer.receive();
            TextMessage textMessageFromReplyQueue = (TextMessage) messageFromReplyQueue;
                        
        } catch (JMSException ex) {
            Logger.getLogger(MessageSender.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            
        }
        return textMessageFromReplyQueue.getText();        
    }

    @Override
    public void onMessage(Message message) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}



И все прекрасно работает! Сообщения складываются в "Actual" (если опять же смотреть в браузер) и сразу поступают на обработку в приложение обработчика и успешно получает ответ. Есть какие-нибудь мысли по этому поводу?
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309505
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgeny,

Конечно есть, jms в рамках транзакции работает, поэтому в одном методе отправить сообщение и получить ответ на него не получится.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309516
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл ник,

Дело в том, что "обработчик сообщений" работает нормально. Он вполне адекватно обрабатывает сообщения, которые к нему приходят из очереди (например случай с реализацией через сервлет). Даже если из этого браузера очереди послать сообщение - обработчик все делает как нужно. А когда все это добро начинаю возводить в рамках веб сервиса всплывают транзакции, а не просто сообщения. Я не могу понять, почему они являются транзакциям.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309521
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
VorobyevEvgenyзабыл ник,

Дело в том, что "обработчик сообщений" работает нормально. Он вполне адекватно обрабатывает сообщения, которые к нему приходят из очереди (например случай с реализацией через сервлет). Даже если из этого браузера очереди послать сообщение - обработчик все делает как нужно. А когда все это добро начинаю возводить в рамках веб сервиса всплывают транзакции, а не просто сообщения. Я не могу понять, почему они являются транзакциям.
Сообщение, которое я отправляю через веб сервис даже не поступает в "обработчик сообщений". Я немного плаваю в этой теме. Может подскажете правильную реализацию такого взаимодействия WebService <-> JMS.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309624
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgenyVorobyevEvgenyзабыл ник,

Дело в том, что "обработчик сообщений" работает нормально. Он вполне адекватно обрабатывает сообщения, которые к нему приходят из очереди (например случай с реализацией через сервлет). Даже если из этого браузера очереди послать сообщение - обработчик все делает как нужно. А когда все это добро начинаю возводить в рамках веб сервиса всплывают транзакции, а не просто сообщения. Я не могу понять, почему они являются транзакциям.
Сообщение, которое я отправляю через веб сервис даже не поступает в "обработчик сообщений". Я немного плаваю в этой теме. Может подскажете правильную реализацию такого взаимодействия WebService <-> JMS.

Дело в том что сообщение не отправляеться потому что в EJB контэйнере при менеджед транзакция - это декларативная транзакция, по умолчанию она Requared и соответственно ее границы - начало предидущей если была и выход из метода. У тебя транзакция завершаеться после выхода из метода sendMessage(), этот метод в свою очередь ждет сообщения на replyConsumer.receive(); (а сообщение которое ожидает replyConsumer.receive() может быть только после выхода из мтода sendMessage() ) в общем замкнутый круг :)
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309632
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
OOsalivanVorobyevEvgenyпропущено...

Сообщение, которое я отправляю через веб сервис даже не поступает в "обработчик сообщений". Я немного плаваю в этой теме. Может подскажете правильную реализацию такого взаимодействия WebService <-> JMS.

Дело в том что сообщение не отправляеться потому что в EJB контэйнере при менеджед транзакция - это декларативная транзакция, по умолчанию она Requared и соответственно ее границы - начало предидущей если была и выход из метода. У тебя транзакция завершаеться после выхода из метода sendMessage(), этот метод в свою очередь ждет сообщения на replyConsumer.receive(); (а сообщение которое ожидает replyConsumer.receive() может быть только после выхода из мтода sendMessage() ) в общем замкнутый круг :)

Интересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309652
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgeny,

Разбить на два метода.
Послыаете сообщение в очередь, у сообщения устанавливаете атрибут что-то вроде destination. Метод заканчивается сообщение попадает в очередь. На втором конце вы получаете сообщение обрабатываете его и посылаете ответ в destination. Третья фаза - вы слушаете destination и получаете там ответ. Как-то так.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309658
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgeny } catch (JMSException ex) {

}
} catch (Exception e) {
}

Так и пишете? Правда?
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309668
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл ник,

Ну это я понимаю :)
Вопрос в том, что когда я отправляю сообщение "обработчику" я в сообщении указываю временную очередь - TemporaryQueue replyQueue = session.createTemporaryQueue() и textMessage.setJMSReplyTo(replyQueue). А в обработчике достаю эту временную очередь и отправляю ответ а нее. Другими словами, каждый клиент веб сервиса при обращении к методу создает свою временную очередь и ждет ответ в нее... То есть на третьей фазе нужно как то знать ту очередь, которую прилепили к сообщению.

Ладно, сейчас буду пробовать ;-)
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309676
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczVorobyevEvgeny } catch (JMSException ex) {

}
} catch (Exception e) {
}

Так и пишете? Правда?
Да что всех одно и то же цепляет-то? А
Код: java
1.
2.
3.
4.
@Override
    public void onMessage(Message message) {
        //....
    }


В обработчике сообщений вас не смущает? :-) Я постарался удалить все линии кода, которые не относятся к сути проблемы (на мой взгляд не относятся).
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309682
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgenyИнтересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?
Для начала вам нужно определится как должен вести себя Web Service в случае. Он будет держать входящий запрос не важно как долго, пока не получит ответ? Тогда нужно что-то с Future заюзать.
http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309777
OOsalivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczVorobyevEvgenyИнтересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?
Для начала вам нужно определится как должен вести себя Web Service в случае. Он будет держать входящий запрос не важно как долго, пока не получит ответ? Тогда нужно что-то с Future заюзать.
http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html

Вообще с появлением в J2ee6 асинхронных методов необходимость в JMS при асинхронном в заимодействии уже не так критична. Многие задачи решаються через колбэки.

VorobyevEvgenyИнтересно... А каким образом мне тогда нужно изменить логику программы. Я понял, что replyConsumer.receive(); нужно убрать из метода, но как мне тогда получить ответ от "обработчика"?

Можно убрать тразакцию - поставив над методом другой атрибут (например NOT_SUPPORTED), можно использовать бин-менеджет транзакцию и указать ее границы самостоятельно, можно как уже было сказанно выше сделать два бина или (селфпрокси) один отсылает, другой ожидает ответа
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309783
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо! Взлетело вот так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
...
            //requestProducer.send(textMessage);
            this.send(requestProducer, textMessage);
...

    private void send (MessageProducer mp, TextMessage tm) {
        try {
            mp.send(tm);
        } catch (JMSException ex) {
            Logger.getLogger(Authorization.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
...


Blazkowicz, да, будет просто ждать. Предполагается, что обработчик сообщений будет отвечать моментально.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309816
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgenyBlazkowicz, да, будет просто ждать. Предполагается, что обработчик сообщений будет отвечать моментально.
Ну, и кому нужна такая асинхронность, если один ждет другого? :)
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309823
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OOsalivanВообще с появлением в J2ee6 асинхронных методов необходимость в JMS при асинхронном в заимодействии уже не так критична. Многие задачи решаються через колбэки.

С каким ещё "появлением"? Всегда было:
http://docs.oracle.com/javaee/1.4/api/javax/resource/spi/work/WorkManager.html
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309836
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgeny,

По-моему, у вас показательный пример как простые вещи делать сложно. Я бы вынес логику в Session Bean и использовал бы его как напрямую, так и через MDB, когда нужна асинхронность.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309887
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мужики, я не претендую на лучшее решение. Была задача реализовать такое взаимодействие, с вашими подсказками я с ней справился. Спасибо.
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38309905
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VorobyevEvgenyМужики, я не претендую на лучшее решение. Была задача реализовать такое взаимодействие, с вашими подсказками я с ней справился. Спасибо.
"...а то так и будешь всю жизнь ключи подавать" :)
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38310798
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Да, я понимаю о чем вы. Мы с коллегой немного ошиблись выбирая эту технологию, она нам не совсем подходит. Но хочется уже довести дело до конца... Ну или, если поймем, что совсем гиблое дело, то придется свернуть с этого пути.

У меня еще вопросы возникли по этой теме. Когда мы тестили этот пример с использованием сервлета, то у нас на стороне обработчика сообщений получалась аналогия очереди. То есть, каждое следующие сообщение попадало на обработку (в метод onMessage) только после того, как закончится обработка предыдущего (предыдущие сообщение покинет метод onMessage). Это было то, что нам нужно и мы решили прикрутить это решение в наш проект. Сейчас эти транзакции попадают в onMessage напрямую (поступило в очередь - onMessage сразу его подхватывает не зависимо от предыдущего сообщения). Наверное это связанно, с особенностью развертывания, в общем с этим:
OOsalivanДело в том что сообщение не отправляеться потому что в EJB контэйнере при менеджед транзакция - это декларативная транзакция, по умолчанию она Requared
Я в этом не силен. В общем, вы наверное уже поняли к чему я клоню...
Вопрос один, можно ли путем каких либо настроек добиться организации реальной очереди на стороне обработчика? Или проще (я подчеркиваю проще, а не лучше) будет отказаться от JMS и построить на втором сервере очередь используя другие технологии?
...
Рейтинг: 0 / 0
WebService, EJB, JMS сообщение застревает в транзакции
    #38311104
VorobyevEvgeny
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем разобрался чуть-чуть. Тот эффект очереди возникал из-за неправильного открытия/закрытия соединения и сессий или чего то еще. В итоге, спустя некоторое время приложение крешится с невозможностью открывать новые соединения...
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / WebService, EJB, JMS сообщение застревает в транзакции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]