2013-07-25 2 views
1

Спецификация для сеансов JMS предупреждает, что объекты/экземпляры сеанса должны использоваться только в потоке, в котором они созданы , когда экземпляры MessageListener зарегистрированы на сеансе. Однако при использовании объектов MessageConsumer (только) он ничего не говорит о том, чтобы быть потокобезопасным или, точнее, «связанным с потоком».JMS: Можно ли читать через MessageConsumer.receive() в одном потоке, а затем вызвать Session.commit() из другого потока?

http://docs.oracle.com/javaee/1.3/api/javax/jms/Session.html

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

ответ на этот вопрос также предполагает, что Сессии потокобезопасны переплет: Relationship between JMS connections, sessions, and producers/consumers

Однако, может или не может быть некоторыми предположениями автор делает, и вопрос также больше о написании сообщений чем примерно чтение их.

Кто-нибудь знает, можете ли вы прочитать сообщение в сеансе в одном потоке, а затем связать другой поток с сообщением и выполнить фиксацию/откат для сообщения (с сеансом) в этом другом потоке? Только транзакция (или откат) будет вызвана против сеанса из потока обработки - никакие другие вызовы не будут сделаны в цепочке Connection/Session/MessageConsumer/Message. Кроме того, сеанс не будет использоваться для повторного чтения до тех пор, пока не произойдет фиксация/откат. кажется,

следующие вопросы S/O тесно связаны между собой, но не делать не удовлетворительно решить, что я предлагаю:

How to continuously read JMS Messages in a thread and achnowledge them based on their JMSMessageID in another thread?

Reason for a JMS Session object to be used in a single threaded context

В то время как я хотел бы использовать сессию на несколько потоков, никогда не будет перекрывающихся запросов/транзакций сообщений.

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

      • редактировать (26 июля) - - -

Этот вопрос, Using a JMS Session from different threads, кажется, предполагает, что это нормально делать синхронизированные операции с сеансом на разных потоках, но я не уверен, какая версия спецификации указана.

+0

Что касается вашего обновления (26 июля), это то, что я хотел бы указать на мою вторую цитату: вам нужно синхронизировать каждый метод, кроме 'close' , Таким образом, хотя вы сохраняете 10 мс (не создавая отдельный сеанс) вначале, вам придется тратить время на каждый вызов синхронизированного метода позже. Если у вас еще нет такой синхронизации, вы должны в любом случае реорганизовать свой код (и это, возможно, подвержено ошибкам). Возможно, именно по этой причине рекомендация не должна делать это таким образом. – Beryllium

ответ

1

Возможно, вы нашли способ в спецификации.

Цитата из ИХ Sessionhttp://docs.oracle.com/javaee/1.3/api/javax/jms/Session.html

Объекта Session является однопоточным контекстом для производства и потребления сообщений. Хотя он может выделять ресурсы поставщика за пределами виртуальной машины Java (JVM), считается объектом легким JMS.

Так оно однопоточное; и создать его не стоит.

И вы должны обратить внимание на

Тесный является методом только сеанса, который можно назвать в то время как другой метод сеанса выполняется в другом потоке.

Таким образом, вы должны убедиться, что read и commit не перекрываются, например.

С технической точки зрения я бы реорганизовал его; код будет легче читать/поддерживать. Обработка ресурсов (открытие/закрытие) будет осуществляться только в одном потоке (только один метод). Это упростило бы обработку исключений.

[С юридической точки зрения: вы признаете, что делаете что-то «странное» - против рекомендации. Я бы не поставил такую ​​часть программного обеспечения.]

+0

Спасибо за ответ. FWIW, создавая сеанс + требуемый потребитель из сеанса, занимает около 250 мс, по крайней мере, один раз в среде, которую я сейчас использую. Я бы не стал считать это слишком легким :-) – Roboprog

+0

@Roboprog Я согласен, я бы тоже не назвал это легким. Всегда ли это занимает время? Другими словами, если вы создаете еще один сеанс из того же 'QueueConnection', все равно это займет так много времени? Какая JMS-реализация? – Beryllium

+1

Был шанс вернуться и украсить тестовые леса: последующие сеансы + пары сообщений и потребителей занимают от 5 до 10 миллисов. Если бы я сказал, каким аппаратным обеспечением и поставщиком сообщений это было, кто-то, вероятно, подал бы мне иск за плохой, несанкционированный бенчмаркинг :-) – Roboprog