[melbourne-pug] django db race conditions

Rasjid Wilcox rasjid at familywilcox.net
Wed Oct 16 05:01:11 CEST 2013


On 16/10/2013 12:27 PM, Brian May wrote:
>
> As an example, for the first case happens when displaying a webpage. 
> Lets assume init_object() is relatively slow. As the web page takes a 
> while to load, the user clicks reload. This results in two (or more) 
> objects being created with name="woof" in error.

For this, I would use a nonce so that you can pick up the duplicate 
posts.  Where to generate the nonce (client side or server side) and 
when to generate the nonce will depend on your actual workflow.  But the 
point of the nonce is that it should allow you know that the second post 
is a 'duplicate' and discard it.

>
> Another example, for the second case occurs when a JavaScript app 
> makes concurrent calls to the web service.
>
> Some people have suggested that if I I want name to be unique, I 
> should make it a database constraint. However that is not always the 
> case that I want these values to be strictly unique, I just want to 
> reuse an existing entry or create it if it doesn't exist. Also, the 
> database constraint would mean the code fails instead of committing 
> two objects, which is not really helpful.

A nonce might possibly work with this too, although (and I'm reading 
between the line here a little), I'm guessing you have two requests that 
really should be called in sequence.  If in the javascript you have 
call_one, followed by call_two, and call_two should be done after 
call_one on the server, you either need wait for call_one to complete 
before calling call_two (but this will make things slow since you get 
the full network latency showing), or have a new back-end method 
(multicall) where you essentially tell the server to do call_one, then 
call_two (but sent as a single request).  This may be able to be 
generalised into a 'batch' call method that could be re-used in various 
situations.

Anther idea could be that you sequence each request from the client (1, 
2, 3, ...) for a given session, with the server effectively placing them 
in a queue (relates to your celery idea).  The only issue I can see with 
the this option is what happens if a request gets lost.  Suppose the 
client sends request 1, 2 and 3, but number 2 gets lost.  It will need 
some timeout on, so that upon getting request 3, it will wait for 
request 2 for a little while, but not too long, and either return an 
error (request 2 missing) or just process after a certain delay.

That is all my idea for the moment.  :-)

Cheers,

Rasjid.



More information about the melbourne-pug mailing list