Hacker News new | past | comments | ask | show | jobs | submit login

Django's transaction-related behavior is documented and configurable. ATOMIC_REQUESTS, which the author complains about, causes Django to automatically wrap each request/response cycle in a transaction. This can be good or bad, depending on the workload, the database, the database's configuration and the types of responses you're sending out (streaming responses might not fully render until after the automatic transaction commits!). So it's off by default.

Django also lets you have fine-grained control of when code will or won't execute in a transaction, so relying solely on transaction isolation (when code might not be running in a transaction, either due to global configuration or local override, and which may be a bad idea anyway -- see next paragraph) doesn't get you all the way to safety for get_or_create()/update_or_create(), hence the documentation recommends you either be careful or use query parameters which involve DB-level uniqueness constraints. Also, for the record, you can tell Django to only query for or update a particular set of columns on a model when round-tripping to and from the DB; the default behavior when you don't explicitly specify a set of columns is to retrieve or insert all of them.

The advice to use READ COMMITTED on MySQL is due to MySQL. On SQLite, the only available behavior is equivalent to SERIALIZABLE. On Postgres, REPEATABLE READ guarantees that, once a transaction begins, changes made in other concurrent transactions will not be visible to it. On MySQL... REPEATABLE READ guarantees that, once a transaction begins, changes made in other concurrent transactions will not be visible to SELECT queries. INSERT, UPDATE and DELETE, however, still see those changes and will happily bomb you out with integrity errors because you did a SELECT (in order to determine whether to follow up with INSERT or UPDATE) and another transaction changed the data you were working with. So on MySQL, REPEATABLE READ is discouraged. If your workload can handle it, by all means use SERIALIZABLE instead, but most people can't and so end up with READ COMMITTED, which at least reduces the window of opportunity for another transaction to make surprising changes to data you're working with. Django also provides access to SELECT FOR UPDATE to allow locking rows you're about to mess with.

I've skimmed the rest of the article and it appears to mistake abrasiveness for honesty and hyperbole for insight, with a healthy dose of representing subjective disagreement over design as a matter of objective correctness or incorrectness. But if you've got questions about other claims it makes, I'm willing to answer them.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: