2013-07-25 34 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

雖然我想用一個會話上的多個線程,永遠不會有重疊的消息請求/事務。我試圖避免進一步重構現有的代碼,所以我正在考慮做一些有點奇怪的事情,而不是在每個工作線程上有一個會話。

      • 編輯(7月26日) - - -

這個問題,Using a JMS Session from different threads,似乎表明它是確定做同步操作在不同的線程上進行會話,但我不確定哪個版本的規範被引用。

+0

至於你的更新(編輯7月26日),這是我想指出的第二次報價:你必須同步除'close 。因此,當您最初節省10毫秒(通過不創建單獨的會話)時,您必須稍後花費時間在每個同步的方法調用上。如果你還沒有這種同步,無論如何你必須重構你的代碼(這可能很容易出錯)。可能這就是建議不這樣做的原因。 – Beryllium

回答

1

也許你已經找到了規範中的一種方法。

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

會話對象的doc由報價是用於製造和使用消息的單線程上下文。儘管它可以在Java虛擬機(JVM)之外分配提供者資源,但它被認爲是一個輕量級的JMS對象。

所以它是單線程的;創建一個並不昂貴。

而且你必須要注意

Close方法,而在另一個線程中執行其他一些會話方法可以被稱爲只有會話方法。

因此,您必須確保readcommit不會重疊,例如。

從技術角度來看,我會重構它;代碼將更容易閱讀/維護。資源處理(打開/關閉)僅在一個線程(一種方法)中。這也會簡化異常處理。

[從法律角度來看:您承認自己正在做一些「奇怪」的事情 - 違背了建議。我不會提供這樣一個軟件。]

+0

感謝您的回答。 FWIW,從會話中創建一個會話+所需消費者大約需要250毫秒,至少在我目前正在使用的環境中執行一次。我不會認爲這太輕:-) – Roboprog

+0

@Roboprog我同意,我不會稱之爲輕量級。它總是需要那段時間嗎?換句話說,如果你從同一個'QueueConnection'創建另一個會話,它是否還需要那麼長時間?哪個JMS實現是它? – Beryllium

+1

有機會返回並修飾測試腳手架:隨後的會話+消息 - 消費者對需要大約5到10毫秒才能完成。如果我說什麼是硬件和消息供應商,那麼有人可能會因我的糟糕的未經授權的基準測試而起訴我:-) – Roboprog

相關問題