[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