Предотвращается ли чтение половинных значений при подсказке SELECT WITH (NOLOCK)?

0

Я думаю, что это вопрос между СУБД, хотя я указываю его в терминологии SQL Server.

Прочитав документацию msdn, например, [1], я не мог понять:

Можно ли выбрать частично написанные) частично перезаписанные, -updated, -deleted, -интегрированные значения значения WITH (NOLOCK), а если нет, то как это (недописанные значения чтения) предотвращено (если блокировки отсутствуют уважаемый)?

Нарушение того, какой принцип СУБД читает полу-письменное значение?
У меня возникают трудности с определением его термина (это целостность, целостность)?
Как называется соответствующий термин?

Обновление:
Я удалил из этого поста вопросы об UPDATE (DELETE) WITH (NOLOCK).

msdn docs, например, [1] и несколько статей сообщают, что SELECT WITH (NOLOCK) совпадает с READUNCOMMITTED и "Нет общих блокировок для предотвращения других транзакций от изменения данных, прочитанных текущей транзакцией, и эксклюзивных блокировок установленные другими транзакциями, не блокируют текущую транзакцию от чтения заблокированных данных".

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

Update2:
Поскольку этот вопрос начал уменьшаться и закрываться, я переместил вопросы на UPDATE (DELETE) WITH (NOLOCK) на форум msdn:

Я также повторил этот же вопрос в форуме msdn:

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

[1] Табличные подсказки (Transact-SQL)
SQL Server 2008 R2
http://msdn.microsoft.com/en-us/library/ms187373.aspx

Теги:
database
sql-server

2 ответа

0
Лучший ответ

После некоторого созерцания и экспериментирования, я считаю, что СУБД не обеспечивают такую ​​целостность ценности:

  • Если бы мы предполагали такую ​​возможность, то мы сразу же приходим к выводу, что одна и та же транзакция в той же области транзакций может использовать неполно определенные (записанные, вставленные, обновленные, удаленные) значения, которые на самом деле никогда не происходят;
  • Значения используются не только СУБД, но и вне ее операционной системой и другими программными платформами.

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

Обновление:
Ответ Гэри поддерживает его:

"Эти защелки - это очень низкие операции ЦП и только для очень коротких периодов времени".

Хотя, я не собирался смешивать обсуждение явлений транзакции транзакций СУБД с низкоуровневой поддержкой транзакций, предоставляемой аппаратным обеспечением.

Update2:
И как было бы лучше назвать соответствующий низкоуровневый (аппаратная поддержка транзакций) отчетливо, чтобы избежать его путаницы и несогласованности с терминологией транзакций СУБД? Является ли это целостностью ценности или целостностью ценности?

Update3:
Предположим, у меня есть строка 2 ГБ в nvarchar (max) с 1 ГБ ОЗУ. Как ЦП обеспечит целостность этого значения на аппаратном уровне?

Ответ Razvan Socol в msdn thread Является ли полунаписанное значение чтения недопустимым WITH (NOLOCK) подсказкой? дает script улавливая чтение частично обновленных значений. Этот сайт в настоящее время недоступен, и я повторно создаю этот код здесь:

1) Создайте тестовую таблицу и заполните 10 строк:

if object_id('Test') IS not NULL
drop table Test;

CREATE TABLE Test (
  ID int IDENTITY PRIMARY KEY,
  Txt nvarchar(max) NOT NULL
)
GO
-----------
INSERT INTO Test
SELECT REPLICATE(CONVERT(nvarchar(max), 
     CHAR(65+ABS(CHECKSUM(NEWID()))%26)),100000)
GO 10
---

2)
На первом сеансе (вкладке SSMS) запускается многозадачное обновление:

UPDATE Test 
SET Txt=REPLICATE(CONVERT(nvarchar(max),
           CHAR(65+ABS(CHECKSUM(NEWID()))%26)),100000)

GO 1000 

3)
Во втором сеансе (вкладке SSMS) запускается захват полузасыщенных значений:

WHILE 1=1 BEGIN
  SELECT Txt FROM Test WITH (NOLOCK) 
  WHERE LEN(REPLACE(Txt,LEFT(Txt,1),''))<>0;
  select 'rowcount inside=',@@rowcount;
  IF @@ROWCOUNT<>0 BREAK
END
--for wishing to try it in non-SqlServer DBMS
-- WITH(NOLOCK) hint is another way as setting READ UNCOMMITTED tx iso level
--SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

Ну, SSMS SQL Server 2008 R2 довольно быстро поймает кучу полузаписанных значений.
Мне любопытно, каковы результаты в других СУБД?

4

Oracle не разрешает грязные чтения ни при каких обстоятельствах (т.е. чтение других незанятых значений сеанса). Он нарушает "Изоляцию" (I в ACID) для базы данных и потенциально дает очевидную несогласованность для операции чтения [например, просмотр ребенка запись без родителя].

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

Тот же механизм также используется для согласованности по времени. Если выбор начался в 3 часа дня, и он обнаружил блок, измененный в 3:02 вечера, то он возвращает историю назад, чтобы найти версию блока, которая была текущей в 3:00. Затем он может обнаружить, что запись, которую он хочет, была заблокирована в 15:00 [это, возможно, было совершено в 3:01 вечера], и ей нужно вернуться назад, чтобы узнать, какое значение было совершено в 15:00.

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

  • 0
    +1 Спасибо за "очень низкий уровень операций ЦП". Я бы предпочел не смешиваться с явлениями транзакций высокого уровня, предоставляемыми СУБД, см. Мой ответ stackoverflow.com/questions/4278884/…. Буду признателен за ссылки на это. Во всяком случае, как называется соответствующий термин? Это постоянство ценностей или целостность ценностей? Как это отличить от терминологии СУБД?
  • 0
    Есть некоторые детали более низкого уровня на andreynikolaev.wordpress.com/2009/10/04/general-spin-lock
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню