3đ
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.
10đ
select_for_update
isnât fragile.
I wrote that âif you were relying on âautomatic transactionsââ then you need to review your code when you upgrade from 1.5 from 1.6.
If you werenât relying on âautomatic transactionâ, and even more if the concept doesnât ring a bell, then you donât need to do anything.
As pointed out in yuviâs answer (which is very good, thank you!) Django will raise an exception when it encounters invalid code. Thereâs no need to think about this until you see a TransactionManagementError
raised by select_for_update
.
4đ
The answer is just around the corner, in the docs for select_for_update (emphasis mine):
Evaluating a queryset with select_for_update in autocommit mode is an
error because the rows are then not locked. If allowed, this would
facilitate data corruption, and could easily be caused by calling,
outside of any transaction, code that expects to be run in one.
In other words, thereâs a contradicting behaviour between autocommit
and select_for_update
, which can cause data corruption. Hereâs the django developerâs discussion where they first proposed solving this issue, to quote (again, emphasis mine):
[âŠ] under Oracle, in autocommit mode, the automatic commit happens
immediately after the command is executed â and so, trying to fetch
the results fails for being done in a separate transaction.However, with any backend, select-for-update in autocommit mode
makes very little sense. Even if it doesnât break (as it does on
Oracle), it doesnât really lock anything. So, IMO, executing a
query that is a select-for-update in autocommit mode is probably en
error, and one that is likely to cause data- corruption bugs.So Iâm suggesting we change the behavior of select-for-update queries,
to error out [âŠ] This is a backwards-incompatible change [âŠ]
These projects should probably be thankful â they were running with a
subtle bug that is now exposed â but still.
So it was an Oracle-only bug, which shown light over a deeper problem thatâs relevant for all backends, and so they made the decision to make this an error in django.
Atomic
, on the other hand, only commits things to the database after it has verifying that there are no errors, thus solving the issue.
- [Django]-Django.core.exceptions.ImproperlyConfigured: Requested setting REST_FRAMEWORK
- [Django]-Redirect realtime common line output to Django HttpResponse
- [Django]-How do I deploy my Vue js SPA into my Django server?
- [Django]-Remove keys from array in django rest framework serializer