You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@click.apache.org by ha...@welinux.cl on 2009/03/17 22:38:14 UTC

Transactions behavior race condition

Hi,

I have an strange behavior with transactions.

I have a system where users must upload a document and then wait for this to be aproved:

-> upload document -> doc aproved -> you can upload other

...as you can see, latter if the document is aproved, then they are allowed to upload another one.

As you can see, in this model, each user should have at most one document waiting to be validated.

The problem is that if i open "more than one document uploading window" and press submit at once, eventually a race condition arise and two documents get registered, breaking the business rule.

Playing with the filter configuration in web.xml, i changed session-scope to true.

Magically this make the things work as expected and you can only upload one document, and the race condition is eliminated.

This solves the problem, but introduces another worst, sessions now see stale data, each session has its own version of the instances.

Please help.


Hans




Re: Transactions behavior race condition

Posted by Bob Schellink <sa...@gmail.com>.
Bob Schellink wrote:
> You mean you only want one request to be processed at a time for all 
> users? In that case you could synchronize on
> the ServletContext which is application scoped:
> 
> public void onInit() {
>    Context context = getContext();
>    synchronize(context.getServletContext()) {
> 
>    }
> }


Just to reiterate, the above statement will effectively block the 
entire application from other users while the document validation 
process in progress. You probably don't want that unless that the 
server is only used by a single user...

bob

Re: Transactions behavior race condition

Posted by Bob Schellink <sa...@gmail.com>.
hans@welinux.cl wrote:
> Bob,
>
> Great, thanks a lot, it's a pure java solution and is working fine.
>
> It's clear that if i would like to preserve other sessions trying to do the same, i should use a global object, in this case, could i use the ClickServlet or something like that ?
>   

You mean you only want one request to be processed at a time for all 
users? In that case you could synchronize on
the ServletContext which is application scoped:

public void onInit() {
    Context context = getContext();
    synchronize(context.getServletContext()) {

    }
}


bob

Re: Transactions behavior race condition

Posted by ha...@welinux.cl.
Bob,

Great, thanks a lot, it's a pure java solution and is working fine.

It's clear that if i would like to preserve other sessions trying to do the same, i should use a global object, in this case, could i use the ClickServlet or something like that ?

Hans

----- "Bob Schellink" <sa...@gmail.com> escribió:

> Bob Schellink wrote:
> > 
> >> The problem is that if i open "more than one document uploading 
> >> window" and press submit at once, eventually a race condition arise
> 
> >> and two documents get registered, breaking the business rule.
> 
> 
> Btw it seems as if you want to use Transaction isolation to serialize
> 
> the upload requests. If that is the case I don't think transactions is
> 
> the ideal way to solve this. Rather synchronize on the session object:
> 
> e.g:
> 
>    public void processDocument(File file, Context context) {
>      HttpSession session = context.getSession();
> 
>      // concurrent requests will queue up here
>      synchronize(session) {
> 
>        validateDocument(file);
> 
>      }
>    }
> 
> The above assumes validation is done by an automatic process. If it 
> requires human intervention or the validation process takes a long 
> time, you might want to think about using asynchronous requests and 
> dumping the documents into a Queue to be processed later.
> 
> I'm sure there are many other ways to approach the problem as well.
> 
> kind regards
> 
> bob

-- 
Hans Poo, WeLinux S.A.
Oficina: 697.25.42, Celular: 09-319.93.05
Bombero Ossa # 1010, Santiago


Re: Transactions behavior race condition

Posted by Bob Schellink <sa...@gmail.com>.
Bob Schellink wrote:
> 
>> The problem is that if i open "more than one document uploading 
>> window" and press submit at once, eventually a race condition arise 
>> and two documents get registered, breaking the business rule.


Btw it seems as if you want to use Transaction isolation to serialize 
the upload requests. If that is the case I don't think transactions is 
the ideal way to solve this. Rather synchronize on the session object: 
e.g:

   public void processDocument(File file, Context context) {
     HttpSession session = context.getSession();

     // concurrent requests will queue up here
     synchronize(session) {

       validateDocument(file);

     }
   }

The above assumes validation is done by an automatic process. If it 
requires human intervention or the validation process takes a long 
time, you might want to think about using asynchronous requests and 
dumping the documents into a Queue to be processed later.

I'm sure there are many other ways to approach the problem as well.

kind regards

bob

Re: Transactions behavior race condition

Posted by Bob Schellink <sa...@gmail.com>.
Hi Hans,

hans@welinux.cl wrote:
> Hi,
> 
> I have an strange behavior with transactions.
> 
> I have a system where users must upload a document and then wait for this to be aproved:


How long will the approval process take? Is this a manual task?


> The problem is that if i open "more than one document uploading window" and press submit at once, eventually a race condition arise and two documents get registered, breaking the business rule.
> 
> Playing with the filter configuration in web.xml, i changed session-scope to true.
> 
> Magically this make the things work as expected and you can only upload one document, and the race condition is eliminated.


I assume you are using Cayenne?

What most likely happens with session-scope is that your transaction 
blocks the second upload request at the session level. Once it commits 
the second request is processed.


> This solves the problem, but introduces another worst, sessions now see stale data, each session has its own version of the instances.


The DataContextFilter has a "autoRollback" property (defaults to true) 
which automatically rolls back uncommitted changes in the DataContext. 
Have you set this to false perhaps? You should not see stale data if 
you rollback uncommitted changes.


kind regards

bob