Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atomic block behaviour #11

Closed
pkaczynski opened this issue Nov 30, 2018 · 2 comments
Closed

Atomic block behaviour #11

pkaczynski opened this issue Nov 30, 2018 · 2 comments

Comments

@pkaczynski
Copy link

This would be a question actually, but it will clarify the documentation for me, so I would be grateful if you could elaborate on this. What would be the assumed behaviour in the following scenario:

with transaction.atomic():
    # Code A
    with transaction.atomic():
        x = get_next_value('test')
        # Code B
    # Code C
  1. Thread is invoking Code B instructions - are other threads blocked waiting (on which line?) until it ends to run Code B? What about Code A?
  2. Thread is invoking Code C instructions. Are other threads blocked waiting (on which line?) until it ends to run Code C? Code B? Code A?

I know the library guarantees than get_next_value always return concurrent gapless values. But for example if I assign this value to an Invoice number in Code B and something goes wrong, there may be a chance that the next transaction would get the next number (in case execution of Code B does not block other threads).

Thank in advance for any answer.

@aaugustin
Copy link
Owner

If two threads run this code concurrently, thread 2 will block on the get_next_value call and won't start executing # Code B until thread 1 finishes executing # Code C.

This is fairly easy to test by replacing # Code X with print("enter X"); time.sleep(10); print("exit X") and running the script in two terminals side by side.

If you try it, I'm interested in a confirmation that the behavior is indeed what I predicted.

PS - if you enabled the ATOMIC_REQUESTS option (which you probably did if you care enough about transactions to look at django-sequences) then the outer atomic block is created by Django and wraps the entire view.

@pkaczynski
Copy link
Author

Thanks for the reply. I can confirm your elaboration. I tested it "manually" using debugger and indeed, thread 2 would block until Code C is fully executed. It works like nesting atomic blocks.

And as to your PS - I did not enable ATOMIC_REQUESTS, and did it deliberately. I do not want requests to be atomic. This is actually the only case I need locking and syncing between requests. I do not want to loose performance :]

Thanks again for the clarification!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants