2013-05-14 2 views
10

Указывает ли стандарт SQL порядок блокировки для запроса с несколькими таблицами?Что определяет порядок блокировки для запроса с несколькими таблицами?

Например, если:

SELECT department.id FROM permissions, terminals, departments WHERE department.id = ? AND terminal.id = ? AND permissions.parent = department.id AND permissions.child = terminals.id;

  1. Гарантирует ли стандарт SQL заказ запирающий или она определяется (реализации конкретного плана выполнения)?
  2. Есть ли способ гарантировать порядок блокировки?
  3. Если нет способа гарантировать порядок блокировки, как мы должны предотвращать взаимоблокировки?

UPDATE: Пожалуйста, не голосуйте, чтобы закрыть этот вопрос, не объясняя ваши рассуждения. Насколько мне известно, это вопрос программирования, который делает его очень актуальным для Stackoverflow. Если вы считаете, что вопрос нуждается в дальнейшем уточнении, объясните, и я буду более чем счастлив ответить вам.

+1

Запросы SELECT не генерируют блокировки, которые приводят к взаимоблокировкам. Можете ли вы перефразировать свой вопрос, чтобы он соответствовал реальной ситуации? –

+1

@GordonLinoff, SELECT запросы в READ_COMMITTED создают генерации блокировок (но на время выполнения инструкции). Для других уровней изоляции (например, REPEATABLE_READ или SERIALIZABLE) они сохраняют блокировку до конца транзакции. Предостережение: в некоторых базах данных используется MVCC, который не использует блокировки, но они не подходят для этого вопроса. – Gili

+1

Замки - это деталь реализации. Уровни изоляции просто определяют явления, которые могут/не встречаться. В SQL Server выбор запросов при чтении выполняется в основном с помощью блокировки 'S', которые освобождаются, как только данные считываются (до конца инструкции). Иногда эти блокировки могут храниться до тех пор, пока утверждение не завершится [пример] (http://blogs.msdn.com/b/craigfr/archive/2007/05/31/read-committed-and-large-objects.aspx) и в других случаях он не принимает блокировки на уровне строки 'S'. При заданной точке 1 точки 2 и 3 являются неопровержимыми, если вы не укажете определенную СУБД. –

ответ

5

Согласно https://stackoverflow.com/a/112256/14731 порядок блокировки определяется порядком исполнения, специфичным для реализации. Далее в дальнейшем говорится, что не существует детерминированного способа предотвращения взаимоблокировок. В то время как в императивном программировании мы можем предотвратить взаимоблокировки, приобретя блокировки в том же порядке, кажется, что в декларативных системах мы должны обойти их, повторив операцию, когда обнаружен тупик.

Кроме того, я утверждаю, что, поскольку планы исполнения базы данных изменяются в течение их жизни, технически невозможно предотвратить взаимоблокировки.

+0

Обратите внимание, что фраза «при доступе к таблицам в том же порядке» в ответе, который вы упомянули, относится к порядку операторов обновления. Порядок таблиц в запросе соединения не будет иметь большого влияния на вероятность тупика, потому что запрос создает только S-блокировки. Две транзакции, выполняющие один и тот же запрос, не будут блокировать друг друга. – nakosspy

+0

@nakosspy, две транзакции, запрашивающие один и тот же набор таблиц, но в другом порядке могут вызвать тупик (по крайней мере, для наивной реализации БД). Другими словами, я согласен с вами в том, что выполнение одного и того же запроса не приведет к тупиковой ситуации, но дело в том, что даже «SELECT» без «UPDATE» может вызвать тупик. – Gili

+2

Что значит наивная реализация базы данных? БД, которая бы приобрела эксклюзивные блокировки для запроса? Я не знаю никакой базы данных, которая делает это. Однако в случае, когда вам приходится иметь дело с такой «наивной» базой данных, основной проблемой будет целостность данных и производительность, а не взаимоблокировки. – nakosspy

1

Я могу дать вам ответ для DB2, но я думаю, что это должно быть аналогично для других баз данных. Прежде всего, все зависит от параметра locksize ваших таблиц. Этот параметр определяет, что блокируется. У вас может быть locksize = table, page или row. Таким образом, в зависимости от блокировки каждой таблицы база данных блокирует объект (таблицу, страницу или строку), который используется для извлечения данных для курсора. Таким образом, порядок создаваемых блокировок будет определяться путем доступа, который зависит от оптимизатора.

+0

Значит, вы говорите, что это зависит от конкретного плана выполнения? Если это так, то как насчет вопроса 3? – Gili

+0

Прежде всего, эти замки являются S замками. Это означает, что никакая другая транзакция не позволяет обновлять страницы (или строки), используемые курсором. Если вы откроете курсор, и уровень изоляции будет считаться устойчивым, то никто не сможет изменять данные, которые читает ваш курсор. Вашей транзакции разрешено изменять эти данные. Если вы хотите минимизировать блокировки, то предпочитаете блокировку строк по странице или таблице и установите уровень изоляции на стабильность курсора. – nakosspy

Смежные вопросы