2010-12-15 4 views
0

Я использую SELECT...FOR UPDATE запросы для блокировки таблицы. К сожалению, у меня есть ситуации, когда мне нужно, чтобы зафиксировать два различных набора строк в одной таблице, например, так:блокировка одной и той же таблицы дважды

SELECT * FROM mytable WHERE attribute1 = 'something' FOR UPDATE 
SELECT * FROM mytable WHERE attribute2 = 'somethingelse' FOR UPDATE 
UPDATE mytable SET attribute2 = 'somethingnew' WHERE somethingelse 

Мне нужно заблокировать оба набора строк. Я делаю это, убедившись, что ни один из объектов в таблице не находится в определенном состоянии, а затем находит другие объекты, которые могут быть помещены в это состояние и помещены туда. Цель состоит в том, чтобы удовлетворить определенные ограничения, которые слишком сложны для кодирования в mysql.

Итак ... вопрос в том, что происходит, когда я SELECT...FOR UPDATE дважды из той же таблицы внутри одной и той же транзакции? Выпускается ли первый замок? Я видел доказательства того, что это так, но я не могу понять, как это подтвердить.

+0

Вы установили autocommit в 0 или начали транзакцию перед выдачей SELECT? – outis 2010-12-15 15:58:13

ответ

0

Как о чем-то вроде

SELECT * FROM mytable WHERE attribute1 = 'something' 
    or attribute2 = 'somethingelse' FOR UPDATE 

UPDATE mytable SET attribute2 = 'somethingnew' WHERE somethingelse 

Я не знаю ответ непосредственно на ваш вопрос, но руководство MySQL говорит запирает выпущен, когда транзакция завершается (фиксируется или откатывается), который означает, что в секунду select не освобождает блокировки. В вашем случае вам фактически не нужны два выбора.

0

Замки выпускаются только при фиксации или откате. С другой стороны, одна транзакция никогда не блокирует для себя. Таким образом, это должно быть хорошо, если только один поток делает это.

Если несколько потоков работают выше, я боюсь, что вы можете зайти в тупик. Если вы этого хотите, вам понадобится один оператор SQL, который блокирует оба набора одновременно, например. Ответ Джайди выше.

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