Hi,
In trying to move on from my deadlock I’ve been pondering how to move the “little” bit of logic in the inner transaction.atomic() (and should take minimal time to run) outside the scope of the outer transaction.atomic() which protects a “much larger” piece of code (which take minutes to run).
Now, I see that the docstring of transaction.Atomic says:
Since database connections are thread-local, this is thread-safe.
...
This is a private API.
I think that means that both connections and transactions have thread-affinity as opposed to process-affinity, and that reorganising my code to use a separate thread for the inner transaction might be a way out. However I don’t see any mention of the affinity in the docs so I wanted to check if thread-affinity is considered part of the API contract or subject to change?
Thanks, Shaheed
Note: In the common case, you do not want to start a thread from within a view, especially if that thread is expected to last longer than the view.
If you’ve got processing that needs to continue beyond the time required for the view to complete, then you really want to spin it off to an external process using something like Celery or Tasks.
@KenWhitesell Understood; this is all safely inside Celery.
I can’t speak for whether creating threads will help with your dead locking situation but this statement is correct.
Members of django.db.connectionsare stored in a context-local abstraction meaning that transactions associated with them share the same affinity.
If you use an entry of django.db.connections (e.g. indirectly by making requests through the ORM) in the main thread of a process and you create a second thread in this process where you access the same member (e.g. connections[DEFAULT_DB_ALIAS]) the second thread will use a distinct database connection.
@charettes Thank you.
Would there be any interest in a documentation patch to make the thread-affinity explicit?
Have you confirmed this is not already documented in some form?
I’ve found these tidbits by searching for “thread” and “transaction”
It seems like the first item’s following statement is explicit enough?
Since each thread maintains its own connection