tags:

views:

201

answers:

2

I have a Django project in which multiple processes are accessing the backend mysql db. One process is creating records, while a second process is trying to read those records. I am having an issue where the second process that is trying to read the records can't actually find the records until I manually call connection._commit().

This question has been asked before: http://stackoverflow.com/questions/952216/caching-issues-in-mysql-response-with-mysqldb-in-django

The OP stated that he solved the problem, but didn't quite explain how. Can anyone shed some light on this? I'd like to be able to access the records without manually calling _commit().

Thanks,

Asif

A: 

Are you running the processes as views? If so, they're probably committing when the request is finished processing, but it sounds like you're running these processes concurrently. If you run the process outside of a view, they should commit on each save.

smokey_the_bear
+3  A: 

He said:

Django's autocommit isn't an actual autocommit in the db.

So, you have to ensure that autocommit is set at the db level. Otherwise, because of transaction isolation, processes will not see changes made by a different process (different connection), until a commit is done. AFAIK this is not especially a Django issue, other than the lack of clarity in the docs about Django autocommit != db autocommit.

Update: Paraphrasing slightly from the MySQL docs:

REPEATABLE READ is the default isolation level for InnoDB. For consistent reads, there is an important difference from the READ COMMITTED isolation level: All consistent reads within the same transaction read the snapshot established by the first read. (My emphasis.)

So, with REPEATABLE READ you only get, on subsequent reads, what was read in the first read. With READ COMMITTED, each read creates and reads its own fresh snapshot, so that you see subsequent updates from other transactions. So - in answer to your comment - your change to the transaction level is correct.

Vinay Sajip
I had autocommit set at to true at the db level. I did a little more digging around and came upon the tx_isolation system variable. Mine was set to REPEATABLE-READ, which is the default for MySQL. After looking at the documentation, I learned that I probably wanted this variable set to READ-COMMITTED. I made the change and things seem to be working correctly now. Can someone confirm that this is the correct solution for my issue?
Asif Rahman