📄 jms6.html
字号:
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <title>Creating Robust JMS Applications</title> <link rel="StyleSheet" href="document.css" type="text/css" media="all" /> <link rel="StyleSheet" href="catalog.css" type="text/css" media="all" /> <link rel="Table of Contents" href="J2EETutorialTOC.html" /> <link rel="Previous" href="JMS5.html" /> <link rel="Next" href="JMS7.html" /> <link rel="Index" href="J2EETutorialIX.html" /> </head> <body> <table width="550" summary="layout" id="SummaryNotReq1"> <tr> <td align="left" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a> </td> <td align="center" valign="center"><a accesskey="p" href="JMS5.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="JMS7.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a> </td> <td align="right" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font> </font> </td> </tr> </table> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"> <blockquote><a name="wp81710"> </a><h2 class="pHeading1">Creating Robust JMS Applications</h2><a name="wp81712"> </a><p class="pBody">This section explains how to use features of the JMS API to achieve the level of reliability and performance your application requires. Many people choose to implement JMS applications because they cannot tolerate dropped or duplicate messages and require that every message be received once and only once. The JMS API provides this functionality.</p><a name="wp81713"> </a><p class="pBody">The most reliable way to produce a message is to send a <code class="cCode">PERSISTENT</code> message within a transaction. JMS messages are <code class="cCode">PERSISTENT</code> by default. A <em class="cEmphasis">transaction</em> is a unit of work into which you can group a series of operations, such as message sends and receives, so that the operations either all succeed or all fail. For details, see <a href="JMS6.html#wp81843">Specifying Message Persistence</a> and <a href="JMS6.html#wp92878">Using JMS API Local Transactions</a>.</p><a name="wp81726"> </a><p class="pBody">The most reliable way to consume a message is to do so within a transaction, either from a queue or from a durable subscription to a topic. For details, see <a href="JMS6.html#wp81884">Creating Temporary Destinations</a>, <a href="JMS6.html#wp81941">Creating Durable Subscriptions</a>, and <a href="JMS6.html#wp92878">Using JMS API Local Transactions</a>.</p><a name="wp81745"> </a><p class="pBody">For other applications, a lower level of reliability can reduce overhead and improve performance. You can send messages with varying priority levels--see <a href="JMS6.html#wp81860">Setting Message Priority Levels</a>--and you can set them to expire after a certain length of time (see <a href="JMS6.html#wp81871">Allowing Messages to Expire</a>).</p><a name="wp81767"> </a><p class="pBody">The JMS API provides several ways to achieve various kinds and degrees of reliability. This section divides them into two categories:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp81768"> </a><div class="pSmartList1"><li><a href="JMS6.html#wp81775">Using Basic Reliability Mechanisms</a></li></div><a name="wp81769"> </a><div class="pSmartList1"><li><a href="JMS6.html#wp81932">Using Advanced Reliability Mechanisms</a></li></div></ul></div><a name="wp81770"> </a><p class="pBody">The following sections describe these features as they apply to JMS clients. Some of the features work differently in J2EE applications; in these cases, the differences are noted here and are explained in detail in <a href="JMS7.html#wp82114">Using the JMS API in a J2EE Application</a>.</p><a name="wp86529"> </a><p class="pBody">This section includes three sample programs, which you can find in the directory <code class="cCode"><</code><code class="cVariable">INSTALL</code><code class="cCode">>/j2eetutorial14/examples/jms/advanced/src/</code>, along with a utility class called <code class="cCode"><a href="../examples/jms/advanced/src/SampleUtilities.java" target="_blank">SampleUtilities.java</a></code>.</p><a name="wp93253"> </a><p class="pBody">To compile the programs in advance, go to the <code class="cCode"><</code><code class="cVariable">INSTALL</code><code class="cCode">>/j2eetutorial14/examples/jms/advanced</code> directory and use the following <code class="cCode">asant</code> target:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">asant build<a name="wp86532"> </a></pre></div><a name="wp81775"> </a><h3 class="pHeading2">Using Basic Reliability Mechanisms</h3><a name="wp81776"> </a><p class="pBody">The basic mechanisms for achieving or affecting reliable message delivery are as follows:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp81777"> </a><div class="pSmartList1"><li><b class="cBold">Controlling message acknowledgment.</b> You can specify various levels of control over message acknowledgment.</li></div><a name="wp81778"> </a><div class="pSmartList1"><li><b class="cBold">Specifying message persistence.</b> You can specify that messages are persistent, meaning that they must not be lost in the event of a provider failure.</li></div><a name="wp81779"> </a><div class="pSmartList1"><li><b class="cBold">Setting message priority levels.</b> You can set various priority levels for messages, which can affect the order in which the messages are delivered.</li></div><a name="wp81780"> </a><div class="pSmartList1"><li><b class="cBold">Allowing messages to expire.</b> You can specify an expiration time for messages, so that they will not be delivered if they are obsolete.</li></div><a name="wp81781"> </a><div class="pSmartList1"><li><b class="cBold">Creating temporary destinations.</b> You can create temporary destinations that last only for the duration of the connection in which they are created.</li></div></ul></div><a name="wp81785"> </a><h4 class="pHeading3">Controlling Message Acknowledgment</h4><a name="wp81786"> </a><p class="pBody">Until a JMS message has been acknowledged, it is not considered to be successfully consumed. The successful consumption of a message ordinarily takes place in three stages.</p><div class="pSmartList1"><ol type="1" class="pSmartList1"><a name="wp81787"> </a><div class="pSmartList1"><li>The client receives the message.</li></div><a name="wp81788"> </a><div class="pSmartList1"><li>The client processes the message.</li></div><a name="wp81789"> </a><div class="pSmartList1"><li>The message is acknowledged. Acknowledgment is initiated either by the JMS provider or by the client, depending on the session acknowledgment mode.</li></div></ol></div><a name="wp81790"> </a><p class="pBody">In transacted sessions (see <a href="JMS6.html#wp92878">Using JMS API Local Transactions</a>), acknowledgment happens automatically when a transaction is committed. If a transaction is rolled back, all consumed messages are redelivered.</p><a name="wp81797"> </a><p class="pBody">In nontransacted sessions, when and how a message is acknowledged depends on the value specified as the second argument of the <code class="cCode">createSession</code> method. The three possible argument values are:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp81799"> </a><div class="pSmartList1"><li><code class="cCode">Session.AUTO_ACKNOWLEDGE</code>. The session automatically acknowledges a client's receipt of a message either when the client has successfully returned from a call to <code class="cCode">receive</code> or when the <code class="cCode">MessageListener</code> it has called to process the message returns successfully. A synchronous receive in an <code class="cCode">AUTO_ACKNOWLEDGE</code> session is the one exception to the rule that message consumption is a three-stage process as described above. </li></div><a name="wp81800"> </a><p class="pBodyRelative">In this case, the receipt and acknowledgment take place in one step, followed by the processing of the message.</p><a name="wp81804"> </a><div class="pSmartList1"><li><code class="cCode">Session.CLIENT_ACKNOWLEDGE</code>. A client acknowledges a message by calling the message's <code class="cCode">acknowledge</code> method. In this mode, acknowledgment takes place on the session level: Acknowledging a consumed message automatically acknowledges the receipt of <em class="cEmphasis">all</em> messages that have been consumed by its session. For example, if a message consumer consumes ten messages and then acknowledges the fifth message delivered, all ten messages are acknowledged.</li></div><a name="wp81806"> </a><div class="pSmartList1"><li><code class="cCode">Session.DUPS_OK_ACKNOWLEDGE</code>. This option instructs the session to lazily acknowledge the delivery of messages. This is likely to result in the delivery of some duplicate messages if the JMS provider fails, so it should be used only by consumers that can tolerate duplicate messages. (If the JMS provider redelivers a message, it must set the value of the <code class="cCode">JMSRedelivered</code> message header to <code class="cCode">true</code>.) This option can reduce session overhead by minimizing the work the session does to prevent duplicates.</li></div></ul></div><a name="wp81807"> </a><p class="pBody">If messages have been received from a queue but not acknowledged when a session terminates, the JMS provider retains them and redelivers them when a consumer next accesses the queue. The provider also retains unacknowledged messages for a terminated session with a durable <code class="cCode">TopicSubscriber</code>. (See <a href="JMS6.html#wp81941">Creating Durable Subscriptions</a>.) Unacknowledged messages for a nondurable <code class="cCode">TopicSubscriber</code> are dropped when the session is closed.</p><a name="wp81815"> </a><p class="pBody">If you use a queue or a durable subscription, you can use the <code class="cCode">Session.recover</code> method to stop a nontransacted session and restart it with its first unacknowledged message. In effect, the session's series of delivered messages is reset to the point after its last acknowledged message. The messages it now delivers may be different from those that were originally delivered, if messages have expired or higher-priority messages have arrived. For a nondurable <code class="cCode">TopicSubscriber</code>, the provider may drop unacknowledged messages when its session is recovered.</p><a name="wp81816"> </a><p class="pBody">The sample program in the next section demonstrates two ways to ensure that a message will not be acknowledged until processing of the message is complete.</p><a name="wp83602"> </a><h5 class="pHeading4">A Message Acknowledgment Example</h5><a name="wp83605"> </a><p class="pBody">The <code class="cCode"><a href="../examples/jms/advanced/src/AckEquivExample.java" target="_blank">AckEquivExample.java</a></code> program in the directory <code class="cCode"><</code><code class="cVariable">INSTALL</code><code class="cCode">>/j2eetutorial14/examples/jms/advanced/src/</code> shows how the following two scenarios both ensure that a message will not be acknowledged until processing of it is complete:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp83606"> </a><div class="pSmartList1"><li>Using an asynchronous message consumer--a message listener--in an <code class="cCode">AUTO_ACKNOWLEDGE</code> session</li></div><a name="wp83607"> </a><div class="pSmartList1"><li>Using a synchronous receiver in a <code class="cCode">CLIENT_ACKNOWLEDGE</code> session</li></div></ul></div><a name="wp83608"> </a><p class="pBody">With a message listener, the automatic acknowledgment happens when the <code class="cCode">onMessage</code> method returns--that is, after message processing has finished. With a synchronous receiver, the client acknowledges the message after processing is complete. (If you use <code class="cCode">AUTO_ACKNOWLEDGE</code> with a synchronous receive, the acknowledgment happens immediately after the <code class="cCode">receive</code> call; if any subsequent processing steps fail, the message cannot be redelivered.)</p><a name="wp83609"> </a><p class="pBody">The program contains a <code class="cCode">SynchSender</code> class, a <code class="cCode">SynchReceiver</code> class, an <code class="cCode">AsynchSubscriber</code> class with a <code class="cCode">TextListener</code> class, a <code class="cCode">MultiplePublisher</code> class, a <code class="cCode">main</code> method, and a method that runs the other classes' threads. </p><a name="wp83610"> </a><p class="pBody">The program uses the following objects:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp86537"> </a><div class="pSmartList1"><li><code class="cCode">jms/Queue</code> and <code class="cCode">jms/Topic</code>, the queue and topic that you created in <a href="JMS5.html#wp80290">Creating JMS Administered Objects</a></li></div>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -