Комментарии 26
Снова перевод документации на хабре. Но порадуемся за тех, кто программирует по харбрахабру, им будет полезно.
Я наверно еще слишком неопытный разработчик, и у меня не было необходимости разбираться в блокировках, лишь поверхностно почитав. Так вот, мне кажется что даже такие, как Вы выразились «переводы документации» все равно полезны, по крайней мере я углубил хоть и немного свои знания, и при необходимости буду знать куда копать)
Обязательно порадуемся. Только это не перевод документации. Безусловно она тут присутствует в какой-то степени, было бы странно ее не использовать (добавить небылиц от себя?). В доках вся информация раскидана по куче статей, здесь же пересказана в кратком виде с пояснениями и примерами.
Кода-то давно, когда я работал с 1С, была очень хорошая дока с описанием уровней изоляций транзакций, она мне очень нравилась тогда. Я ее себе сохранил.
Ссылка.
Много про сам 1С, но понять смысл можно. Кто бы сделал реферат? Так же есть базовое описание что такое блокировка вообще.
Ссылка.
Много про сам 1С, но понять смысл можно. Кто бы сделал реферат? Так же есть базовое описание что такое блокировка вообще.
SELECT… FOR UPDATE — блокирует считываемые строки на чтение.
на чтение для обновления? или вообще любое чтение будет заблокировано?
на чтение для обновления? или вообще любое чтение будет заблокировано?
Какое счастье, что когда-то кто-то изобрел MVCC…
select… for update как раз позволяет бороться с этим «счастьем», но иногда да, MVCC бывает полезно
Ну, в большинстве случаев стандартное поведение с откатом и повтором вполне устраивает. Что важнее — оно более интуитивно понятно, и тяжелее выстрелить себе в ногу дедлоком.
Ох, я вас уверяю, MVCC в непривычного человека стреляет куда больнее. Deadlock по крайней мере трудно не заметить.
Ну так и конфликт при записи не заметить тоже очень сложно.
Если вы имели в виду что-то другое — поясните, пожалуйста.
Если вы имели в виду что-то другое — поясните, пожалуйста.
Пример хорошо описан у Кайта, повторять не буду. Вкратце: человек переходит (например на Oracle) с блокировочника и «ваяет» систему, по привычке держа в голове, что писатели блокируют читателей и наоборот. Получается нехорошо, лечится for update-ом. С подобной ситуацией я сталкивался лично, когда софт одного крупного мобильного оператора писался людьми, до этого плотно работавшими с MS SQL 2000 и имевшими об Oracle отдаленное представление.
Ну это вами же описан классический случай подхода, «не надо RTFM, разберемся по ходу дела». Но я, опять же, не вижу принципиальной разницы с таким же переходом в обратную сторону, когда человек с MVCC переходит на блокирующий сервер и получает дедлок в той ситуации, которая успешно разруливается MVCC. И в том, и в другом случае опасность в том, что на это можно нарваться не сразу, а погодя (в продакшне, например). Но когда нарываешься, то диагностика в обоих случаях вполне однозначная.
Именно так. MVCC — хороший инструмент (разумеется с собственными накладными расходами), но надо уметь им правильно пользоваться, чтобы не прострелить себе ногу. Высказывания о том какое это «счастье», на мой взгляд, не побуждают к чтению документации и поиску пятен на Солнце. И это плохо.
Мне кажется, вы все-таки смотрите слишком однобоко. Если оставить в стороне ситуации типа кто-то переходит с чего-то, и рассмотреть абстрактного разработчика в вакууме, который осваивает это все с нуля, то объяснить ему поведение снэпшотов в MVCC, и как с ними правильно работать, на мой взгляд, в разы проще («всегда будь готов к тому, что записывающая транзакция при коммите может обломиться, и её надо будет повторить»). А вот с блокировками надо писать статьи, подобные этой, где детально разбирается поведение блокировщика — кто там на что берет какой лок — разные уровни изоляции etc.
При этом снэпшоты обеспечивают поведение от оптимального до «good enough» в большинстве случаев без каких-либо приседаний вообще. С блокировками, опять же, надо очень внимательно продумавать, какие уровни изоляции где использовать, и как все это будет взаимодействовать друг с другом.
При этом снэпшоты обеспечивают поведение от оптимального до «good enough» в большинстве случаев без каких-либо приседаний вообще. С блокировками, опять же, надо очень внимательно продумавать, какие уровни изоляции где использовать, и как все это будет взаимодействовать друг с другом.
Ну и по поводу «стреляет больнее». Возможность Deadlock-а можно не заметить, но если он случается достаточно часто (а так оно обычно и бывает), это будет заметно и за это разработчика будут долбать, пока он его не исправит. Ошибки проектирования связанные с непониманием MVCC коварнее. Выявить их можно, как правило, только анализируя некорректное поведение системы. И, как правило, такое некорректное поведение бывает связано с чьими-то денежными средствами.
А чего вы человека заминусовали-то? Это ж не сарказм, вроде бы… :-)
Приложения обычно больше читают, нежели пишут. MVCC позволяет читателям не стоять в очереди и не мешать писателям.
Приложения обычно больше читают, нежели пишут. MVCC позволяет читателям не стоять в очереди и не мешать писателям.
Так как блокировок две, то есть теоретический шанс проскочить третьей между ними и вызвать deadlock.
Я так понимаю, что это происходит из-за того, что чтобы поставить эксклюзивную блокировку FOR UPDATE надо сначала снять блокировку от изменения LOCK IN SHARE MODE. В этот промежуток между двумя блокировками и успевает вклиниться другая транзакция, так? Это актуально только для MySQL или все реляционные БД ведут себя подобным образом?
Верно. В простейшем виде блокировки, это некая очередь. Если блокировке мешает предыдущая, она не отваливается с ошибкой, она просто встает в очередь. Как только мешающая блокировка будет снята, следующая по очереди вступит в силу. Две блокировки — два действия постановки в эту очередь, соответственно между этими действиями может кто-то еще успеть встать в эту очередь между ними.
В базовом виде, думаю, суть с постановкой в очередь примерно одинакова в различных СУБД, но, полагаю, что у всех есть алгоритмы для предотвращения deadlock'ов, которые работают с этой очередью и могут ее тасовать каким-нибудь хитрым образом. Утверждать не берусь, ибо не знаю.
В базовом виде, думаю, суть с постановкой в очередь примерно одинакова в различных СУБД, но, полагаю, что у всех есть алгоритмы для предотвращения deadlock'ов, которые работают с этой очередью и могут ее тасовать каким-нибудь хитрым образом. Утверждать не берусь, ибо не знаю.
Господа, а кто-нибудь может привести более-менее внятный реальный пример, когда нужно использовать SERIALIZABLE / SELECT… LOCK IN SHARE MODE? Мне не доводилось сталкиваться с такими случаями и сходу придумать могу. А то в статье рассмотрен пример, когда не надо его использовать, а надо использовать SELECT… FOR UPDATE (с такими случаями я как раз сталкивался).
SERIALIZABLE — это когда сделал на read committed и select for update, протестировал, задеплоил и через год посыпались deadlock-и и срочно стало нужно спасать ситуацию…
Представьте дерево или граф, которые пользуются и в хвост и в гриву :-)
Нужно вставить дочерний узел. Перед вставкой нужно убедиться в существовании родителя. Делаем SELECT, убеждаемся, делаем вставку и получаем «foreign key constraint fails» — родителя кто-то успел грохнуть. LOCK IN SHARE MODE в данной ситуации не позволит никому потереть родителя до завершения транзакции, а FOR UPDATE будет излишним, так как не даст другим читать родителя.
SERIALIZEABLE. Вот сваяли вы соц сеть, а с приходом популярности в логах стали появляться ошибки из примера выше. Включаете SERIALIZEABLE и идете рыть код… ну или пиво пить.
Нужно вставить дочерний узел. Перед вставкой нужно убедиться в существовании родителя. Делаем SELECT, убеждаемся, делаем вставку и получаем «foreign key constraint fails» — родителя кто-то успел грохнуть. LOCK IN SHARE MODE в данной ситуации не позволит никому потереть родителя до завершения транзакции, а FOR UPDATE будет излишним, так как не даст другим читать родителя.
SERIALIZEABLE. Вот сваяли вы соц сеть, а с приходом популярности в логах стали появляться ошибки из примера выше. Включаете SERIALIZEABLE и идете рыть код… ну или пиво пить.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Блокировки и уровни изоляции транзакций InnoDB в MySQL