how to make serial process using MDB and activemq in java

201 views Asked by At

i am working on ejb mdb using activemq, could you please help me, iam read the message from queue and save the data into database, i am able to save the data into database but it mdb takes the message from the queue, one message is partially save into database ,then another message is processed. I want to save the messages into database one by one, could any one help me

2

There are 2 answers

0
Amit On

EJBs aid in distributed processing. MDB helps you to scale the system by processing multiple messages arriving in a queue or topic it is bound to.

There is a configuration that says how many beans should be in a pool and consuming the messages. You can configure it to 1 and it will behave the way you expect ( presuming you have one app server).

However if you really want to process messages one after another then using MDB does not make sense. You could write a plain java class that implements MessageListener. But this will slow your entire process down and there is a chance messages keep piling up in the queue.

0
Ermal On

The explanation of @Amit is correct, if you configure maxSession to 1 the behavior will be one you expect. This is the cleanest way to achive single consuling.

In case your need is not to run only 1 MDB per time, but only to be sure that in certain time only one thread executes the code (db update for example), than you can use Singleton present in EJB3.1. Your code will look something like:

@MessageDriven(...)
public class MessageReceiver implements MessageListener {

    @EJB(name = "DBSingleton")
    private DBSingleton dbSingleton;

    public void onMessage(Message jmsMessage) {

        //here a lot of, time consuming operations

        User u; //get it from jmsMessage
        dbSingleton.updateUser(u);
    }
}


@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) 
@Singleton
public class DBSingleton {

    @EJB(name = "UserService")
    private UserService userService;

    @Lock(LockType.READ)
    public User getUsers() {
        return userService.getUser();
    }

    @Lock(LockType.WRITE)
    public void updateUser(User user) {
        userService.updateUser(user);
    }
}

UserService  uses  EntityManager to persist in DB (directly or indirectly through a DAO class)


Last way to achive this, but discouraged from ejb specific, is to use synchronized block.


See: Concurrency in Message Driven Bean - Thread safe Java EE5 vs. EE6