Search code examples
jpaglassfishejbeclipselink

EJB - Commit and flush within a MDB


I have a message driven bean which is communicating with a database via EntityManager. The EM is injected via @PersistenceContext, like normal. I want to flush changes to an Entity immediately without waiting for the MDB to fully complete its processing of the given Message.

For example:

MDB's onMessage() {
  Foo f = em.find(Foo.class, 123);
  f.setNewStatus("Performing work!");
  em.merge(f);
  em.flush();
  ...
  // Continue doing a lot of work...
  ...

  f.setNewStatus("Done!");
  em.merge(f);
  em.flush();
}

The problem is that I never see the "Performing Work!" status from outside the context of the MDB (e.g. by logging into the DB directly and checking the tuple's value).

This appears to be related to transactions. From online material, it sounds like a transaction is started within the context of onMessage() and not committed until the method is complete. Hence, the intermediate status is never committed since we eventually write "Done!" which overwrites the Foo's value within the PersistentContext.

Is there a solution to this type of problem? Some way to control the context of the transaction?


Solution

  • I think what you want to achieve is to see changes from outside of the transaction before this transaction commits. Well this is only possible when transaction isolation is set to Read uncommitted which I dont think is default in your DB.

    What you can do is to add method, that will log your data, with attribute: @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

    In this case, container will have to pause current transaction, create new one that will executed in this method, and when it finishes, main transaction will be resumed.