2013-06-17 3 views
5

Django documentation утверждает, что:select_for_update в разработке Django

Если вы полагались на «автоматических операций», чтобы обеспечить блокировку между select_for_update() и последующей операции записи - в чрезвычайно хрупкой конструкции, но тем не менее, возможно, - вы должны обернуть соответствующий код в atomic().

Причина, по которой это больше не работает, заключается в том, что autocommit выполняется на уровне базы данных, а не на уровне приложения? Ранее сделка would be held open until a data-altering function is called:

поведение Джанго по умолчанию для работы с открытой сделкой, которую он берет на себя обязательство автоматически, когда любые встроенными данные изменяющая модель функции называется

А с Django 1.6, с автокоммиттом на уровне базы данных, что select_for_update, за которым следует, например, write, фактически будет работать в двух транзакциях? Если это так, то не select_for_update стал бесполезным, поскольку его точка была lock the rows until a data altering function was called?

+0

Autocommit на уровне базы данных пришел с django 1.6, а не 1.5. – fabspro

+0

@fabspro thanks - исправлено – Taras

ответ

5

select_for_update будет блокировать только выбранную строку в контексте одной транзакции. Если вы используете autocommit, он не будет делать то, что, по вашему мнению, он делает, потому что каждый запрос будет фактически собственной транзакцией (включая запрос SELECT ... FOR UPDATE). Оберните свой вид (или другую функцию) в transaction.atomic, и он сделает то, что вы ожидаете от него.

+0

Это то, что я думал о документации, но если это правда, не делает функцию select_for_update бесполезной (поскольку ее первоначальной причиной было блокирование затронутых строк до выполнения операции записи) – Taras

+2

@ Тарас - 'select_for_update' делает точно так, как это документировано, но если вы используете его с autocommit, вы по существу получаете и освобождаете блокировку сразу, что не очень помогает. Таким образом, запрос работает одинаково, но без транзакции для поддержания своего рода состояния, как Postgres знает, когда выпустить блокировку (кроме как сразу)? Если он просто удерживал их до записи, представьте плохую программу, которая выбрала группу строк для обновления, а затем вызывает исключение. Выбранные строки будут заблокированы навсегда. – orokusaki

+0

Думаю, я сейчас понимаю. 'select_for_update' не полезен для autocommit, но он ** полезен, когда поведение autocommit не используется, например: когда транзакция явно определена с помощью оператора' atom' ..? – Taras