Какова точная связь между транзакцией базы данных и блокировкой?

16

Это скромный вопрос, заданный в духе расширения моих знаний; будьте любезны в своем ответе.

Как давний разработчик приложений, я знаю на каком-то уровне, что такое транзакция (я использую их все время). Оставляя в стороне уровни изоляции транзакций на данный момент, на высоком уровне транзакция позволяет полностью или совсем не завершить блок работы и обеспечивает определенную степень изоляции от других действий по модификации базы данных.

Я также знаю, что (в различных базах данных) это блокировка или, по крайней мере, как она себя ведет (если я каким-то образом явно блокирую таблицу, то никакой другой процесс или поток не может обновить что-либо об этой таблице).

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

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

Я еще раз прошу прощения за наивность этого вопроса; Я счастлив, что мне указывают на более фундаментальные источники.

Лейрд Нельсон
источник

Ответы:

12

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

Да. Если это не так, то ваша «блокировка» будет ограничена другими подобными «блокировками» и не будет взаимодействовать с собственной блокировкой двигателя. Таким образом, вы бы заблокировали строку в таблице, чтобы она не могла быть заблокирована другим приложением таким же образом, но ваша блокировка была бы проигнорирована самим механизмом. Эта семантика редко желательна. В большинстве случаев приложение, блокирующее строку, означает «заблокировать ее любым средством доступа / изменения». Заметьте, что механизмы блокировки, которые строго зависят от приложения , существуют, потому что они полезны. Например, SQL Server имеет блокировки приложений .

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

Блокировка является одним из способов достижения этого. Основная альтернатива - управление версиями. В настоящее время большинство баз данных поддерживают оба (что также означает, что если вы «блокируете» строку в приложении, но другая транзакция использует версионирование для чтения строки, она будет читать ее, потому что ваша блокировка не блокирует версионное чтение).

Вы как бы вращаетесь вокруг концепции, известной в мире реализации баз данных как «протокол двухфазной блокировки» . связанная статья Википедии - хороший стартер. Если вы хотите прочитать более подробное объяснение по этой теме, я рекомендую отправиться в библиотеку и попросить кредит на обработку транзакций: концепции и методы . Практически каждая база данных по своей сути является реализацией этой книги.

Ремус Русану
источник
Возможно, вы можете добавить о (без блокировки) оптимистическом управлении параллелизмом
ypercubeᵀᴹ
Ага! Сейчас мы говорим. Действительно, в глубине моего сознания скрывался MVCC . Спасибо за хорошо сформулированный ответ, замечательные ссылки и за то, что нашли время по-настоящему разобраться в моем вопросе.
Лейрд Нельсон
3

Немного предыстории, прежде чем отвечать на ваши вопросы:

Примечание. Это относится к Microsoft SQL Server - RDBMS ........

  • Проще говоря, транзакция - это последовательность операций, которая должна быть выполнена как единое логическое устройство в целом и должна поддерживать свойства ACID.
  • Любая СУБД должна предоставлять «средства блокировки», которые можно использовать для полного завершения транзакции, сохраняя изоляцию транзакции и ее долговечность. Это обеспечивает физическую целостность базы данных.
  • Самое главное, по умолчанию - транзакции управляются на уровне соединения. Таким образом, когда транзакция запускается для соединения, все операторы T-SQL (S / I / U / D), выполняемые для этого соединения, являются частью транзакции, пока транзакция не завершится. ( MARS обрабатывается по-разному)

Теперь вернемся к вашим вопросам:

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

Да. Это означает, что вы должны быть осторожны при определении последовательности данных, которые будут изменены и которые приведут базу данных в согласованное состояние. Другими словами, ваша операция DML должна оставлять базу данных в согласованном состоянии, которое ограничивается бизнес-правилами вашей организации. Тем не менее, СУБД (здесь SQL Server) может обеспечить физическую целостность транзакции.

От BOL: Блокировка и управление версиями строк не позволяют пользователям читать незафиксированные данные и не позволяют нескольким пользователям одновременно изменять одни и те же данные. Без блокировки или контроля версий строк запросы, выполненные к этим данным, могут дать неожиданные результаты, возвращая данные, которые еще не были зафиксированы в базе данных.

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

Все в сервере sql содержится в транзакции. Когда вы получаете доступ к своим данным, СУБД должна блокироваться в зависимости от уровня изоляции и операций, которые вы выполняете над своими данными. Проверьте этот ответ для более подробной информации.

Несколько хороших ссылок:

Кин Шах
источник
2

Я бы сказал, что транзакции являются частью «интерфейса» базы данных в том смысле, что вы, как разработчик, решаете, когда начинать, заканчивать, что делать в рамках транзакций и т. Д. Блокировки, на мой взгляд, относятся к деталям реализации. и используется для синхронизации доступа к различным объектам. В большинстве случаев сам двигатель решает, что и на какой срок следует заблокировать. Существует много блокировок системного уровня, которыми нельзя напрямую манипулировать (например, механизм может блокировать определенные области памяти). Даже когда речь идет о блокировках DML, многие из них происходят за кулисами (например, для обеспечения ссылочной целостности Oracle и, насколько я помню, SQLServer может установить блокировку соответствующей строки в основной таблице, если новая запись вставлена ​​в таблица данных) в результате выписок DML, выпущенных в рамках транзакции.

Когда дело доходит до транзакций, вы можете ожидать более или менее согласованного поведения от любой RDMS, которая утверждает, что она соответствует SQL и поддерживает транзакции, но когда дело доходит до блокировок, почти каждый поставщик использует разные стратегии и терминологию. Насколько я могу судить, общая часть всех RMDS состоит в том, что параллелизм между транзакциями определяется уровнем изоляции, тогда как параллелизм между блокировками контролируется типами блокировок (разделяемая, исключительная и т. Д.).

Подводя итог, можно сказать, что блокировки - это низкоуровневый механизм контроля согласованности объектов и параллелизма. Блокировки могут быть выполнены во время выполнения операторов SQL. В зависимости от реализации уровня изоляции транзакции, механизм может устанавливать различные типы блокировок на затронутые объекты (строки, группы строк, индексы и т. Д.). Доступно ограниченное количество команд для ручной блокировки ( SELECT FOR UPDATE, LOCK). Блокировки DML могут быть расширены (зависит от RDMS, например, в SQLServer row-> page-> partition-> table). Блокировки также могут быть выданы ядром базы данных во время инициализации соединения, резервного копирования, восстановления, перекомпиляции процедуры / триггера / функции / и т. Д., Запуска, выключений и т. Д.

Я не уверен, что это отвечает на ваш вопрос, но я надеюсь, что это имеет смысл.

a1ex07
источник
Спасибо за ваш комментарий. Ты определенно самый близкий до сих пор. Я все еще пытаюсь понять, всегда ли транзакции реализуются в терминах блокировок, которые используются, скажем, явными LOCKили SELECT FOR UPDATEоператорами, или через какой-то другой механизм.
Лейрд Нельсон
Насколько я знаю, BEGIN TRANSACTIONсам по себе замков не выдает. Блокировки появятся после DML в транзакции.
a1ex07
Уточнение - я имел в виду, что BEGIN TRANSACTIONсам не создает блокировки DML; на самом деле он должен выдавать некоторые внутренние блокировки, потому что он должен распределять ресурсы, добавлять запись в системную таблицу [s] (если есть), которая содержит активные транзакции, и т. д.
a1ex07
1

Я буду использовать жаргон SQL Server, но концепции должны быть такими же для других поставщиков:

Каждая команда, которую вы выполняете, выполняется внутри транзакции. Эта транзакция может быть открыта явно с помощью BEGIN TRAN или неявно с помощью механизма базы данных. Причина, по которой неявная транзакция открыта, состоит в том, что ядру все еще необходимо поддерживать соответствие ACID и возможность отката.

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

Матан Юнгман
источник
Спасибо за ваш комментарий. Это много я знаю. Но мой вопрос по-прежнему: когда эта транзакция открыта, достигается ли ее изоляция путем удержания собственных замков? Если да, то являются ли эти замки одними и теми же видами замков, которые я могу получить явным образом? Или транзакция достигает изоляции другими способами?
Лейрд Нельсон
2
Да, это тот же механизм. Изоляция достигается с помощью блокировок в обоих режимах, таких же блокировок вы можете явно получить. Разница в том, что если вы не откроете транзакцию в явном виде, блокировки будут сняты после завершения команды, тогда как в явной транзакции блокировки будут удерживаться до момента фиксации (не на 100% с точностью из-за уровней изоляции, но это Главная идея).
Матан Юнгман
Спасибо за ваш комментарий. Причина, по которой я задаю свой вопрос, состоит в том, что я где-то читал, что некоторые базы данных используют MVCC в качестве средства для выполнения транзакций ACID, что, как мне кажется, является способом без блокировки. Тогда в таких случаях мне неясно, когда я захочу явно выполнить блокировку. Но это, наверное, отдельный вопрос. :-)
Laird Nelson
@LairdNelson - это уровень изоляции моментальных снимков для SQL Server. Существующий, но не стандартный механизм для параллелизма. Это по умолчанию для Oracle или Postgresql, хотя, IIRC.
Marian
0

Необходимы блокировки, и они составляют базу данных. Это предотвращает повреждение или аннулирование данных, когда несколько пользователей пытаются читать, а другие записывают в базу данных. Транзакционная изоляция обычно реализуется путем блокировки всего, к чему осуществляется доступ в транзакции. Плохие дизайнерские приложения широко используют концепцию блокировки базы данных :) !! Поэтому, чтобы избежать блокировки, сконцентрируйтесь на своем FK и макете данных.

Это все о кислоте: - прочитайте это, и это очистит ваш разум! ACID - это набор свойств, которые вы хотели бы применить при изменении базы данных.

  • ** Атомарность
  • консистенция
  • изоляция
  • Прочность **

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

Атомарность означает, что вы можете гарантировать, что вся транзакция произойдет или ничего не произойдет; Вы можете выполнять сложные операции как единое целое, все или ничего, а сбой, сбой питания, ошибка или что-либо еще не позволит вам находиться в состоянии, в котором произошли только некоторые связанные изменения.

Согласованность означает, что вы гарантируете, что ваши данные будут согласованы; ни одно из ограничений, связанных с данными, не будет нарушено.

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

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

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

Up_One
источник
Спасибо за ваш комментарий. Я по крайней мере сносно осведомлен о свойствах ACID. Что мне до сих пор не ясно, так это: реализуют ли транзакции ACID с помощью тех же типов блокировок, которые я могу использовать напрямую через явные LOCKоператоры, или они делают это с помощью какого-то другого механизма?
Лейрд Нельсон
Базы данных предлагают несколько уровней изоляции транзакций, которые управляют степенью блокировки, возникающей при выборе данных. Сериализуемое, Повторяемое чтение, Чтение зафиксировано, Чтение незафиксировано.
Up_One