This tech tip takes a clos­er look at what 're­li­able' mes­sag­ing means and how to achieve it. As we will see, it all de­pends on how you con­fig­ure and use your JMS.

About JMS

JMS (Java Mes­sage Ser­vice) is an in­ter­fac­ing tech­nol­o­gy to ac­cess mes­sage servers from with­in your Java or J2EE ap­pli­ca­tion. Dur­ing the last years, JMS has gained enor­mous pop­u­lar­i­ty in the EAI (en­ter­prise ap­pli­ca­tion in­te­gra­tion) busi­ness be­cause of its abil­i­ty to pro­vide so-called re­li­able mes­sag­ing. This tech tip takes a clos­er look at what 're­li­able' mes­sag­ing means and how to achieve it. As we will see, it all de­pends on how you con­fig­ure and use your JMS. But first some vo­cab­u­lary.

De­liv­ery Guar­an­tees

In the con­text of this tech tip, we will dis­tin­guish be­tween dif­fer­ent de­liv­ery guar­an­tees of a mes­sage:

Maybe: in this case, there is ac­tu­al­ly no guar­an­tee. A mes­sage may dis­ap­pear be­fore it can be con­sumed.

At least once: a mes­sage is nev­er lost in the sys­tem, but can be de­liv­ered to the re­ceiv­er more than once (and hence be con­sumed more than once). This im­plies that the re­ceiv­er needs to be pro­grammed with this in mind.

Ex­act­ly once: a mes­sage is nev­er lost and only de­liv­ered once. This is the real re­li­able mes­sag­ing mode.

Reli­able Mes­sag­ing with JMS

Whether or not your mes­sag­ing ap­pli­ca­tion is re­li­able de­pends on the fol­low­ing pa­ra­me­ters:

  • Whether or not mes­sages are per­sist­ed in the JMS serv­er.
  • Which ac­knowl­edge­ment mode is used by the re­ceiv­er.

Clear­ly, if mes­sages are not per­sist­ed then there is al­ways the pos­si­bil­i­ty of los­ing a mes­sage (if the serv­er crash­es be­fore the mes­sage can be de­liv­ered). So in that case, you can only count on Maybe se­man­tics.

How­ev­er, even if mes­sages are per­sist­ed there is still the pos­si­bil­i­ty of los­ing mes­sages (in this tech tip, 'los­ing' a mes­sage is some­what broad­er than as de­fined in the JMS spec­i­fi­ca­tion: we say that a mes­sage is lost if it fails to be processed in the DBMS of the re­ceiv­er). For per­sis­tent mes­sag­ing, all de­pends on the ac­knowl­edge­ment mode. The ac­knowl­edge­ment of a mes­sage trig­gers the dele­tion of the mes­sage on the serv­er.

Mes­sage Ac­knowl­edge­ment Modes

The fol­low­ing modes ex­ist in JMS:

AUTOMATIC ACKNOWLEDGEMENT: this means that a mes­sage is ac­knowl­edged (delet­ed) as soon as the re­ceiv­er gets it.

EXPLICIT ACKNOWLEDGEMENT: this means that the re­ceiv­er has to ex­plic­it­ly tell the serv­er when the mes­sage is no longer need­ed.

TRANSACTIONAL ACKNOWLEDGEMENT: if the re­ceiv­er gets the mes­sages with­in the scope of a JTA trans­ac­tion then ac­knowl­edge­ment is done if and only if the trans­ac­tion com­mits.

Achiev­ing Ex­act­ly-Once Guar­an­tees

The fol­low­ing ta­ble sum­ma­rizes the mes­sage guar­an­tees for each pos­si­ble com­bi­na­tion of these pa­ra­me­ters:

Per­sis­tence mode vs Ac­knowl­edge­ment mode AUTOMATIC EXPLICIT TRANSACTIONAL
NOT PERSISTENT Maybe Maybe Maybe
PERSISTENT Maybe At least once Ex­act­ly once
As you can see, in or­der to have re­li­able mes­sag­ing you need to have trans­ac­tions and per­sis­tence en­abled. Other­wise, be pre­pared to deal with ei­ther mes­sage loss or du­pli­cate mes­sages...

Com­mit Order­ing with JMS

Be­ware if you de­pend on the or­der of com­mits in the data­base and mes­sage queue. See Com­mit Order­ing with JMS for de­tails...

An Ex­am­ple of How Things Can Go Wrong

It is tempt­ing to be­lieve that it suf­fices to use JMS in or­der to achieve ful­ly re­li­able mes­sag­ing, but this is not true.

Let's con­sid­er the fol­low­ing ex­am­ple of where things can go wrong. As­sume that a mes­sage comes in on the JMS queue (say, a pay­ment or­der) and we want to process the pay­ment in the data­base.

  1. The mes­sage is tak­en off the queue
  2. The mes­sage is processed by our Java pro­gram
  3. The re­sults are put in the data­base

Let's now fo­cus on the fol­low­ing ques­tions:

  • Can mes­sages be lost?
  • Can mes­sages be re­ceived twice?

The an­swer to each ques­tion will de­pend on the ac­knowl­edge­ment mode for JMS. Again, the pos­si­ble val­ues are: au­to­mat­ic, ex­plic­it and trans­ac­tion­al.

With au­to­mat­ic ac­knowl­edge­ment, the JMS mes­sage is delet­ed from the queue as soon as it is tak­en off. Clear­ly, this al­lows mes­sage loss if our pro­gram crash­es in step 2. In that case, the pay­ment or­der is lost for­ev­er. Hence, we have mes­sage loss.

With ex­plic­it ac­knowl­edge­ment, the JMS mes­sage is not delet­ed from the queue un­til our pro­gram tells it to do so. When could we tell the JMS to delete the mes­sage? If done be­fore step 2, then a crash in 2 means mes­sage loss again. If done dur­ing step 2, then a crash will also lose the mes­sage since the data­base has not been changed. If done af­ter step 3, then a crash could hap­pen be­tween 3 and be­fore we can delete the mes­sage. In that case, the mes­sage will be re­de­liv­ered upon restart and will be re-processed and re-post­ed to the data­base. That is: du­pli­cates.

With trans­ac­tion­al ac­knowl­edge­ment, there are two pos­si­bil­i­ties: con­nec­tor-lev­el JMS and JDBC trans­ac­tions or JTA/XA. When JMS is used in trans­ac­tion­al mode, the dele­tion of a mes­sage is only done if and only if the trans­ac­tion com­mits. JDBC im­plies that the data­base is up­dat­ed only if the trans­ac­tion com­mits.

For con­nec­tor-lev­el trans­ac­tions, we will have two dis­tinct trans­ac­tions: one for JMS and one for JDBC. So the ques­tion is: how should the com­mits be or­dered to avoid mes­sage loss and du­pli­cates?

If the JMS trans­ac­tion is com­mit­ted first, a crash can hap­pen be­fore we com­mit the JDBC trans­ac­tion. Con­se­quence: mes­sage loss; the pay­ment will nev­er be in the data­base.

If the JDBC trans­ac­tion is com­mit­ted first, a crash can hap­pen be­fore we com­mit the JMS trans­ac­tion. Con­se­quence: du­pli­cate mes­sage; the mes­sage is not delet­ed from the queue and will be re­de­liv­ered lat­er. The ap­pli­ca­tion will re-process it and re-post it in the data­base.

The only re­main­ing pos­si­bil­i­ty is: joint com­mit of both the JMS and the JDBC trans­ac­tion, and this is ex­act­ly what JTA/XA do for you. For re­li­able, ex­act­ly-once mes­sag­ing you re­al­ly need JTA/XA.

Per­for­mance

Per­haps a bit counter-in­tu­itive­ly, XA does not mean bad per­for­mance. It's ac­tu­al­ly the op­po­site - as ex­plained in this post: High per­for­mance JMS pro­cess­ing with XA.

Try For Your­self?

FREE down­load of Trans­ac­tion­sEssen­tials
RSS

Comments

Add a comment

Corporate Information

Atomikos Corporate Headquarters
Hoveniersstraat, 39/1, 2800
Mechelen, Belgium

Contact Us

Copyright 2026 Atomikos BVBA | Our Privacy Policy
By using this site you agree to our cookies. More info. That's Fine