The Django documentation states
If you were relying on “automatic transactions” to provide locking between select_for_update() and a subsequent write operation — an extremely fragile design, but nonetheless possible — you must wrap the relevant code in atomic(). Since Django 1.6.3, executing a query with select_for_update() in autocommit mode will raise a TransactionManagementError.
Why is this considered fragile? I would have thought that this would result in proper transactionality.
Aymeric clarified over email that such a design is fragile because it relies on the implicit transaction boundaries formed by Django 1.5's implicit transactions.
select_for_update(...)
more_code()
save()
This code works in straightforward cases, but if more_code()
results in a write operation to the database, then the transaction would close, producing unintended behavior.
Forcing the user to specify the transaction boundaries also leads to clearer code.