Django transaction.commit() needed after Model.objects.filter() when object was saved from another process
django, multiprocessing, mysql, python
Solution
Since you're using transaction middleware, each request gets a different transaction.
The recommended way to handle transactions in Web requests is to tie them to the request and response phases via Django’s TransactionMiddleware.
It works like this: When a request starts, Django starts a transaction. If the response is produced without problems, Django commits any pending transactions. If the view function produces an exception, Django rolls back any pending transactions.
This means that if the second process's request came in before the write was triggered, its transaction will predate the write. The database will then do the right thing and report the value that was current at the time the second process's transaction was created. Manually committing the second process's transaction before reading is harmless (as long as it has made no edits) and tells the database to create a new transaction. Which will postdate write, and therefore give you the modified results.
Problem
I have two processes running the Django codebase, for various reasons, one process will update an object as follows: ``` myObj.aField = "updated" myObj.save() ``` And later on the other process attempts to read that object as follows: ``` def getObj(xxx): objs = TheModel.objects.filter(xyz=xxx) for obj in objs: print obj.aField ``` When reading the value from the second process, I won't see the updated value, instead I see the old value. The second time around I run the function, I do see the change. I've noticed that if from the second process (the one reading), I change the function as follows, I get the updated value: ``` @transaction.commit_manually def getObj(xxx): objs = TheModel.objects.filter(xyz=xxx) transaction.commit() for obj in objs: print obj.aField ``` After adding the decorator `@transaction.commit_manually` and the `transaction.commit()` line right below the `filter()` call, I do get the updated value from the field (which was saved from the other process.) Is there any reason why this is needed? And what is the impact/potential issues of using `transaction.commit()` on a function that actually does not update models at all? I'm not sure why it works, and if it makes sense, so hopefully someone else ran into this issue. Thanks,