Блокировка для обработки параллелизма — хорошая идея?[закрыто]

StackOverflow https://stackoverflow.com/questions/225625

  •  03-07-2019
  •  | 
  •  

Вопрос

Чтобы решить проблему параллелизма, является ли блокировка - любая форма блокировки, будь то блокировка строк, таблиц или базы данных - хорошим решением?

Если нет, то как решить проблему параллелизма?

Это было полезно?

Решение

Если вы верите Oracle, то нет, вовсе нет.Это потому, что Oracle приложила все усилия, чтобы избежать этого.

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

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

Oracle использует управление версиями строк, где вместо блокировки строки для ее записи создается новая версия строки.Читатели, которым нужно повторить свои чтения, запоминают, какую версию строки они прочитали.Однако произойдет ошибка, если средство чтения, которое запоминает свои чтения, попытается обновить строку, которая была обновлена другим средством записи с момента ее чтения этой транзакцией;это делается для того, чтобы остановить потерю обновлений.Чтобы гарантировать, что вы можете обновить строку, вы должны сказать, что ВЫБОР предназначен ДЛЯ ОБНОВЛЕНИЯ;если вы это сделаете, потребуется блокировка - только одна транзакция может одновременно содержать строку ДЛЯ ОБНОВЛЕНИЯ, и конфликтующей транзакции приходится ждать.

SQL Server 2005 и более поздние версии поддерживают изоляцию моментальных снимков, что является их названием для управления версиями строк.Опять же, вы должны запросить блокировку обновления, если вам нужно обновить некоторые данные, которые вы только что прочитали - в SQL Server используйте WITH (UPDLOCK) .

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

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

Другие советы

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

Блокировка базы данных - в отличие от блокировки таблицы или строки - плохой способ борьбы с параллелизмом; это исключает параллелизм.

Есть много разумных альтернатив, чтобы самостоятельно кодировать блокировку DMBS. Имейте в виду, что на самом деле всегда происходит какая-то блокировка (атомарные действия и т. Д.), Но ключ в том, что вы не хотите идти туда, если вам это не нужно. Вы не хотите обедать с философами, если вам не нужно. Транзакции являются одним из способов обойти блокировку, но это в основном для фиксации. Использование поля, которое помечает / указывает, что запись является грязной, (грязный битовый шаблон) - это другой способ, просто убедитесь, что вы делаете это в режиме атомарного доступа. Язык часто имеет подходящее решение, на которое ссылались предыдущие посты, однако язык, как правило, поддерживает только приложение, процесс для обработки, уровень параллелизма, а иногда параллелизм должен быть в базе данных. Я не хотел предполагать, что у вас есть богатый прикладной уровень, но если вы это сделаете, есть много уровней абстракции, которые обрабатывают это для вас. TopLink от Oracle бесплатен и является более надежным братом Hibernate, оба из которых помогают вам управлять проблемами параллелизма в вашей базе данных с помощью абстракции, грязных битов, кэширования и отложенной блокировки. Вы действительно не хотите реализовывать их самостоятельно, если только вы не программируете для школы или личного проекта. Пойми проблему, но встань на плечи гигантов.

Я думаю, что нет, потому что все кончено " вниз " и делает ваше приложение более сложным. Большинство языков имеют отличные методы обработки параллелизма, и даже тогда лучшим способом является написание кода, который может обрабатывать параллелизм «изначально».

Для получения дополнительной информации о параллелизме в Java: http://java.sun.com/docs/books/ учебник / Эфирные / параллелизм / index.html

Вы имеете в виду обработку параллелизма в вашем приложении или решение проблемы параллелизма с базой данных? Если первое, это не кажется мне хорошим подходом. Если последнее, это может быть ваш единственный ответ без изменения ваших схем.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top