Lets say I have 2 beans. The first we will call DispatchBean and the second HandleBean. DispatchBean finds the appropriate HandleBean accroding to the operation and calls that bean. Then, when it returns, HandleBean commits its actions and then DispatchBean does some logging and returns control to the user. Also assume declarative transaction management. Here is the issue.
HandleBean has to tell the client what to update. Since the client is looking at potentially hundreds of objects and since other clients are looking at the same objects, the client's cache manager needs to be informed to update. All clients looking at the object need to be so informed.
So the solution is to have a JMS event system. As HandleBean finishes the method, it fires off a Message for each object to update. The client cache managers get these messages and call the server to get new data if they are interested in the objects. If not, they ignore the messages.
The problem is this. After implementation, I am finding that sometimes the messages will beat the commit of the data. The client refreshes the data but the commit hasnt gone through and the client fetches the old data again. What I need is a method to make sure the client doesnt get (or more accurately, the server doesnt fire) the messages until the commit has gone through.
Caveats. The return value from the HandlerBean is already taken up by any value the handler may want to pass back to the client so I cant return the objects to chage from the dispatcher.
Can anyone think of a potential resolution?
Well, one option would be to split your HandleBean method into two methods: one with RequiresNew txn that updates the data, and one the calls the first and then fires the message. Be sure to make the call through yuor EJBObject, not directly, so that the RequiresNew takes effect. I am assuming the bean is stateless. Otherwise put the first method in a seperate stateless bean.
The problem with this approach is that it's not 100% transactionally secure: updates could go to the DB, and then the message posting would fail. That's not very likely though, and doesn't sound too fatal.
The scenario you describe sounds pretty weird. I mean, it doesn't sound likely. Are you sure that you don't use an "old" connection in the client, i.e one whose transaction started before you got the message?
You could put the changed data in the message. This might or might not make sense, depending on the size of the data, the proportion of recipients who will want the new data, and the cost of each recipient getting the data from the server (in the current case where it isn't in the message)
What isolation level are you using? A *lower* (READ_UNCOMMITTED) isolation level for the client refresh transaction might help, as long as it doesn't introduce any consistency problems.