Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:


November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:


1. Introduction

Message Driven Beans, also known as “MDB”, handle message processing in an asynchronous context. We can learn the basics of MDB in this article.

This tutorial will discuss some strategies and best practices to implement concurrency using Message Driven Beans.

If you want to understand more about the basics of concurrency using Java, you can get started here.

In order to better use MDBs and concurrency, there are some considerations to make. It's important to keep in mind that those considerations should be driven by the business rules and the needs of our application.

2. Tuning the Thread Pool

Tuning the Thread Pool is probably the main point of attention. To make a good use of concurrency, we must tune the number of MDB instances available to consume messages. When one instance is busy handling a message, other instances are able to pick up the next ones.

The MessageListener thread is responsible to execute the onMessage method of an MDB. This thread is part of the MessageListener thread pool, which means that it's pooled and reused over and over again. This pool also has a configuration that allows us to set the number of threads, which may impact the performance:

  • setting a small pool size will cause messages to be consumed slowly (“MDB Throttling”)
  • setting a very large pool size might decrease performance – or not even work at all.

On Wildfly, we can set this value by accessing the management console. JMS capability isn't enabled on the default standalone profile; we need to start the server using the full profile.

Usually, on a local installation, we access it through After that, we need to access Configuration / Subsystems / Messaging / Server, select our server and click “View”.

Choose the “Attributes” tab, click on “Edit” and change the value of “Thread Pool Max Size”. The default value is 30.

3. Tuning Max Sessions

Another configurable property to be aware of is Maximum Sessions. This defines the concurrency for a particular listener port. Usually, this defaults to 1 but increasing it can give more scalability and availability to the MDB application.

We can configure it either by annotations or .xml descriptors. Through annotations, we use the @ActivationConfigProperty:

@MessageDriven(activationConfig = {
        propertyName=”maxSession”, propertyValue=”50”

If the chosen method of configuration is .xml descriptors we can configure maxSession like this:


4. Deployment Environment

When we have a requirement for high availability, we should consider deploying the MDB on an application server cluster. Thus, it can execute on any of the servers in the cluster and many application servers can invoke it concurrently, which also improves scalability.

For this particular case, we have an important choice to make:

  • make all servers in the cluster eligible to receive messages, which allows the use of all of its processing power, or
  • ensure message processing in a sequential manner by allowing just one server to receive them at a time

If we use an enterprise bus, a good practice is to deploy the MDB to the same server or cluster as the bus member to optimize the messaging performance.

5. Message Model and Message Types

Although this isn't as clear as just setting another value to a pool, the message model and the message type might affect one of the best advantages of using concurrency: performance.

When choosing XML for a message type, for instance, the size of the message can affect the time spent to process it. This is an important consideration especially if the application handles a large number of messages.

Regarding the message model, if the application needs to send the same message to a lot of consumers, a publish-subscribe model might be the right choice. This would reduce the overhead of processing the messages, providing better performance.

To consume from a Topic on a publish-subscribe model, we can use annotations:

  propertyName = "destinationType", 
  propertyValue = "javax.jms.Topic")

Again, we can also configure those values in a .xml deployment descriptor:


If sending the very same message to many consumers isn't a requirement, the regular PTP (Point-to-Point) model would suffice.

To consume from a Queue, we set the annotation as:

  propertyName = "destinationType", 
  propertyValue = "javax.jms.Queue")

If we're using .xml deployment descriptor, we can set it:


6. Conclusion

As many computer scientists and IT writers already stated, we no longer have processors' speed increasing on a fast pace. To make our programs work faster, we need to work with the higher number of processors and cores available today.

This article discussed some best practices for getting the most out of concurrency using MDBs.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until the end of this week:


Generic footer banner
Inline Feedbacks
View all comments
Comments are closed on this article!