You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@geronimo.apache.org by Łukasz Budnik <lu...@gmail.com> on 2008/03/25 13:11:01 UTC

transactions within MDB

Hi All!

I have a problem with transactions within MDB.

The thing is my MDB executes quite large, time-consuming tasks which
can take up to few minutes.

My onMessage looks something like this:

// object message has a task (task has unique ID - known to the end-user)
onMessage(ObjectMessage message) {

// 1. update task status to 'running', set start time and some other
things (logs)
merge(task);

// 2. now time-consuming tasks, up to few minutes...
doIt();

// 3. finalize, change task status to finished/failed, set end time
//     and once again some more logs
merge(task);

}

The problem is that the merge operation from 1st step waits till merge
in 3rd step (to be precise - the return from the onMessage method).

This is a huge problem since my tasks take even up to few minutes.

The end-user knows the ID of the task and can check task status from
the web app.

When task takes 4-5 minutes to complete, user sees the task in 'new'
state for the whole time, and then out of the sudden task becomes
'finished' without entering the 'running' state.

Besides, if something goes wrong, application enters fatal error
during execution of the task there won't be any traces left (only
logs, but end-users don't read them ;) ).

The question is: how can I enforce DB update after each merge.

Note that em.flush() does not force updates in this case and causes
viewTaskState.jsp (select) to hang and wait for the completion of the
onMessage().

Anybody encountered such a problem?

thanks in advance for any hints

best regards
Łukasz

Re: transactions within MDB

Posted by Łukasz Budnik <lu...@gmail.com>.
Hi David,

On 25/03/2008, David Jencks <da...@yahoo.com> wrote:
> You appear to want selective bits of the ACID properties of
>  transactions :-)

Ups.. didn't know that onMessage is a single transaction ;)

> It looks like "task" is a persistent status object with some
> information about other objects that are actually modified during the
> task.

Yes, you have deciphered me correctly ;)
ObjectMessage holds Task and Task is a persistent object.

>  To get more processing status visible to clients you need more
>  transactions, one for each state change that you want to be visible.
>  I can think of two ways to do this:
>
>  1. More mdbs: you split the workflow up into more mdbs where each one
>  updates the status and does some bit of the work, then puts the task
>  (or task ID) onto a queue for the next one.

I'd rather not, I'm afraid of performance issues with chained queues.

>  2. A stateless session bean with a RequiresNew method that you call
>  to update the task with the new status.  With this approach you will
>  probably not want to have the mdb have a copy of the same task object
>  as the SLSB -- at least I don't know exactly what happens when you
>  try to send a persistent object across transaction boundaries.  I'd
>  expect trouble.
>  Hope this gives you hints about a couple ways to proceed

the second piece of advice worked!

I've created new SLSB with REQUIRES_NEW transaction attribute, also
I'm passing id of the task as a parameter, where I simply fetch fresh
copy from DB, modify it and update at the end.

thanks for hints!

best regards
Łukasz

Re: transactions within MDB

Posted by David Jencks <da...@yahoo.com>.
You appear to want selective bits of the ACID properties of  
transactions :-)

I'm pretty sure I don't entirely understand what you are trying to do  
and what the structure of your objects is and which ones are  
persistent.  However.... there might be several ways to proceed.

It looks like "task" is a persistent status object with some  
information about other objects that are actually modified during the  
task.

To get more processing status visible to clients you need more  
transactions, one for each state change that you want to be visible.   
I can think of two ways to do this:

1. More mdbs: you split the workflow up into more mdbs where each one  
updates the status and does some bit of the work, then puts the task  
(or task ID) onto a queue for the next one.
2. A stateless session bean with a RequiresNew method that you call  
to update the task with the new status.  With this approach you will  
probably not want to have the mdb have a copy of the same task object  
as the SLSB -- at least I don't know exactly what happens when you  
try to send a persistent object across transaction boundaries.  I'd  
expect trouble.

Hope this gives you hints about a couple ways to proceed
david jencks

On Mar 25, 2008, at 5:11 AM, Łukasz Budnik wrote:

> Hi All!
>
> I have a problem with transactions within MDB.
>
> The thing is my MDB executes quite large, time-consuming tasks which
> can take up to few minutes.
>
> My onMessage looks something like this:
>
> // object message has a task (task has unique ID - known to the end- 
> user)
> onMessage(ObjectMessage message) {
>
> // 1. update task status to 'running', set start time and some other
> things (logs)
> merge(task);
>
> // 2. now time-consuming tasks, up to few minutes...
> doIt();
>
> // 3. finalize, change task status to finished/failed, set end time
> //     and once again some more logs
> merge(task);
>
> }
>
> The problem is that the merge operation from 1st step waits till merge
> in 3rd step (to be precise - the return from the onMessage method).
>
> This is a huge problem since my tasks take even up to few minutes.
>
> The end-user knows the ID of the task and can check task status from
> the web app.
>
> When task takes 4-5 minutes to complete, user sees the task in 'new'
> state for the whole time, and then out of the sudden task becomes
> 'finished' without entering the 'running' state.
>
> Besides, if something goes wrong, application enters fatal error
> during execution of the task there won't be any traces left (only
> logs, but end-users don't read them ;) ).
>
> The question is: how can I enforce DB update after each merge.
>
> Note that em.flush() does not force updates in this case and causes
> viewTaskState.jsp (select) to hang and wait for the completion of the
> onMessage().
>
> Anybody encountered such a problem?
>
> thanks in advance for any hints
>
> best regards
> Łukasz