Блокировка записей в SQL
От: Аноним  
Дата: 12.10.05 07:29
Оценка:
при установках по дефолту

юзер запускает SELECT на выборку данных

Если Select дошел до толко 3 записи
а в это время другой юзер в транзакции отредактировал 5 запись и не закоммитил
что будет ??
Мое мнение что если выборка была запущена до начала транзакции то она вернет первичные данные не остановившись отвергли как неправельное мнение.

мне сказали что для селекта будет блокировка, но ни как не обосновали это


объясните плз. кто знает !!!!
Re: Блокировка записей в SQL
От: tpg Россия http://www.sql.ru/
Дата: 12.10.05 07:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>при установках по дефолту


А>юзер запускает SELECT на выборку данных


А>Если Select дошел до толко 3 записи

А>а в это время другой юзер в транзакции отредактировал 5 запись и не закоммитил
А>что будет ??
А>Мое мнение что если выборка была запущена до начала транзакции то она вернет первичные данные не остановившись отвергли как неправельное мнение.

А>мне сказали что для селекта будет блокировка, но ни как не обосновали это



А>объясните плз. кто знает !!!!


Блокировки в MS SQL Server 2000
Автор(ы): Алексей Ширшов
Дата: 15.11.2003
В статье рассказывается о уровнях изоляции транзакций и механизме блокировок, обеспечивающем поддержку этих уровней в СУБД MS SQL Server 2000. Предполагается, что читатель хорошо знаком с транзакциями и их свойствами.
Re: Блокировка записей в SQL
От: Merle Австрия http://rsdn.ru
Дата: 12.10.05 07:45
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Мое мнение что если выборка была запущена до начала транзакции то она вернет первичные данные не остановившись отвергли как неправельное мнение.

А>мне сказали что для селекта будет блокировка, но ни как не обосновали это
Зависит от сервера БД и реализации механизма Concurrency Control в оном. Может быть как блокировка, так и чтение предыдущего значения.
Мы уже победили, просто это еще не так заметно...
Re: Блокировка записей в SQL
От: chabster Украина chabster.blogspot.com
Дата: 12.10.05 08:02
Оценка:
> мне сказали что для селекта будет блокировка, но ни как не обосновали это
Если это SELECT ... FOR UPDATE брокировка будет в любом случае.
Если это Oracle можно указать опцию NOWAIT и SELECT просто вернет ошибку.
Если это простой SELECT в случае Oracle блокировки не будет, т.к. запись не блокирует чтение и наоборот. С другими БД SELECT будет блокирован до тех пор, пока не освободятся нужные данные.
Posted via RSDN NNTP Server 1.9
Re[2]: Блокировка записей в SQL
От: AvPyrozhenko Украина  
Дата: 12.10.05 08:05
Оценка:
Здравствуйте, Merle, Вы писали:

А>>Мое мнение что если выборка была запущена до начала транзакции то она вернет первичные данные не остановившись отвергли как неправельное мнение.

А>>мне сказали что для селекта будет блокировка, но ни как не обосновали это
M>Зависит от сервера БД и реализации механизма Concurrency Control в оном. Может быть как блокировка, так и чтение предыдущего значения.

Сервер MSSQL 2000, если можно подробней. В каких сетуациях это может возникнуть.
Пытался смоделировать данную ситуацию но получил то что и утверждал.
Re[3]: Блокировка записей в SQL
От: chabster Украина chabster.blogspot.com
Дата: 12.10.05 08:23
Оценка:
>Сервер MSSQL 2000, если можно подробней. В каких сетуациях это может возникнуть.
Пытался смоделировать данную ситуацию но получил то что и утверждал.

Помоему, в MSSQL 2000 чтение блокирует запись и наоборот (без использования хинтов).
Posted via RSDN NNTP Server 1.9
Re[3]: Блокировка записей в SQL
От: Merle Австрия http://rsdn.ru
Дата: 12.10.05 09:14
Оценка:
Здравствуйте, AvPyrozhenko, Вы писали:

AP>Сервер MSSQL 2000, если можно подробней. В каких сетуациях это может возникнуть.

Во всех. В MSSQL 2000, предыдущую версию записи select не прочтет никогда, будет либо блокировка, либо чтение "грязных" данных незафиксированной транзакции, в зависимости от уровня изоляции.

AP>Пытался смоделировать данную ситуацию но получил то что и утверждал.

Значит что-то не так с моделированием.

T1:
--- Тестовая таблица
---
drop table tst0
create table tst0(i int identity(1,1) PRIMARY KEY, a varchar(50))
insert into tst0 (a) 
select top 10 newID() from sysobjects

--- запрос который будет блокировать наш селект до тех пор, пока мы не запустим другую транзакцию,
которая поменяет нашу "запись номер 5"
begin tran
    update tst0 set a = 'Fake GUID' where i=3


T2:
--- собственно SELECT
---
select * from tst0

Здесь он повиснет на предыдущей транзакции, пока висит, успеем поменять "запись номер 5" в еще одной транзакции, не фиксируя ее...

T3:
begin tran
   update tst0 set a = 'Really Fake GUID' where i=5



Открываем еще одно окошко и смотрим блокировки:

SELECT 
    convert (smallint, req_spid) As spid,
    rsc_dbid As dbid,
    rsc_objid As ObjId,
    so.name as ObjName, 
    rsc_indid As IndId,
    substring (v.name, 1, 4) As Type,
    substring (rsc_text, 1, 16) as Resource,
    substring (u.name, 1, 8) As Mode,
    substring (x.name, 1, 5) As Status
FROM           master.dbo.syslockinfo sl
    INNER JOIN master.dbo.spt_values v ON sl.rsc_type = v.number
    INNER JOIN master.dbo.spt_values x ON sl.req_status = x.number
    INNER JOIN master.dbo.spt_values u ON sl.req_mode + 1 = u.number
    LEFT  JOIN sysobjects so ON sl.rsc_objid = so.ID
WHERE   v.type = 'LR' and x.type = 'LS' and u.type = 'L' and so.Name = 'tst0'
ORDER BY spid

Картина примерно следующая, с точностью до констант, ненужные подробности опущены:
SPID    TableName                       Lock Type  Status
52    tst0    KEY (03000d8f0ecc)      X       GRANT    <-- Блокировка от первого апдейта
53    tst0    KEY (03000d8f0ecc)      S       WAIT     <-- на ней висит select и ждет, обрати внимание на ID ключа в скобочках
54    tst0    KEY (0500d1d065e9)      X       GRANT    <-- Блокировка второго апдейта


Теперь снимаем блокировку, чтобы select выполнялся дальше:
T1:
rollback

С удивлением обнаруживаем, что select по прежнему висит, опять смотрим блокировки:
SPID  TableName                     Lock Type  Status
53    tst0    KEY (0500d1d065e9)      S       WAIT     <-- Теперь select висит на другой блокировке
54    tst0    KEY (0500d1d065e9)      X       GRANT    <-- Блокировка второго апдейта


Теперь фиксируем изменения "записи номер 5" и видим, что селект наконец-то выполнился и прочитал все изменения.
Мы уже победили, просто это еще не так заметно...
Re[2]: Блокировка записей в SQL
От: Igor Trofimov  
Дата: 12.10.05 17:41
Оценка: +1
C>Если это простой SELECT в случае Oracle блокировки не будет, т.к. запись не блокирует чтение и наоборот. С другими БД SELECT будет блокирован до тех пор, пока не освободятся нужные данные.

Ну, ну.. не Ораклом единым
Есть и другие БД, не блокирующие читателей.
Re[4]: Блокировка записей в SQL
От: AvPyrozhenko Украина  
Дата: 13.10.05 07:17
Оценка:
Здравствуйте, Merle, Вы писали:

AP>>Сервер MSSQL 2000, если можно подробней. В каких сетуациях это может возникнуть.

M>Во всех. В MSSQL 2000, предыдущую версию записи select не прочтет никогда, будет либо блокировка, либо чтение "грязных" данных незафиксированной транзакции, в зависимости от уровня изоляции.

AP>>Пытался смоделировать данную ситуацию но получил то что и утверждал.

M>Значит что-то не так с моделированием.

Вы не совсем правельно поняли:
Выборка запущена до начала транзакции а не после неё как вы описали в примере.

При моделировании у меня вышло
что селект при установках по умолчанию возвращаются первичные данные.
если же запускать select в транзакции с uncomited то возвращаются уже измененные даные.

но влюбом случае select запущенный до начала транзакции не останавливается
Re[5]: Блокировка записей в SQL
От: Merle Австрия http://rsdn.ru
Дата: 13.10.05 07:58
Оценка:
Здравствуйте, AvPyrozhenko, Вы писали:

AP>Вы не совсем правельно поняли:

AP>Выборка запущена до начала транзакции а не после неё как вы описали в примере.
Там есть две транзакции, одна запущена до начала выборки, другая после. И обе вызывают блокировку выборки.

AP>При моделировании у меня вышло

AP>что селект при установках по умолчанию возвращаются первичные данные.
Такого не может быть (за исключением ситуации описанной ниже), если нет ошибок в коде SQL Server-а отвечающего за параллельную обработку данных, во что я признаться не верю.

AP>но влюбом случае select запущенный до начала транзакции не останавливается

Это может быть только в том случае если селект уже выбрал данные, которые меняет транзакция запущенная после селекта.
Выборка не обращается ко всем данным одновременно, а последовательно перебирает все необходимые записи, и если пишущая транзакция поменяет данные, которые селект уже просмотрел, то естественно будет иллюзия, что селект прочитал предыдущую версию. Но если пишущая транзакция поменяет данные, до которых селект еще не добрался, то будет блокировка.
... << RSDN@Home 1.1.4 beta 7 rev. 0>>
Мы уже победили, просто это еще не так заметно...
Re[6]: Блокировка записей в SQL
От: AvPyrozhenko Украина  
Дата: 13.10.05 08:13
Оценка:
Здравствуйте, Merle, Вы писали:

M>Здравствуйте, AvPyrozhenko, Вы писали:


AP>>Вы не совсем правельно поняли:

AP>>Выборка запущена до начала транзакции а не после неё как вы описали в примере.
M>Там есть две транзакции, одна запущена до начала выборки, другая после. И обе вызывают блокировку выборки.
это я заметил, почему и написал что возможно вы не поняли ситуацию.

AP>>При моделировании у меня вышло

AP>>что селект при установках по умолчанию возвращаются первичные данные.
M>Такого не может быть (за исключением ситуации описанной ниже), если нет ошибок в коде SQL Server-а отвечающего за параллельную обработку данных, во что я признаться не верю.

не ошибается только тот кто ничего не делает

AP>>но влюбом случае select запущенный до начала транзакции не останавливается

M>Это может быть только в том случае если селект уже выбрал данные, которые меняет транзакция запущенная после селекта.
M>Выборка не обращается ко всем данным одновременно, а последовательно перебирает все необходимые записи, и если пишущая транзакция поменяет данные, которые селект уже просмотрел, то естественно будет иллюзия, что селект прочитал предыдущую версию. Но если пишущая транзакция поменяет данные, до которых селект еще не добрался, то будет блокировка.

как можно объяснить следуещее (моделирование проводил на 100к записей, менял последнию)
select при установках по умолчанию возвращает первичные данные.
select в транзакции с uncomited возвращает уже измененные даные.
Re[7]: Блокировка записей в SQL
От: _d_m_  
Дата: 13.10.05 08:33
Оценка:
Здравствуйте, AvPyrozhenko, Вы писали:


AP>>>При моделировании у меня вышло

AP>>>что селект при установках по умолчанию возвращаются первичные данные.
M>>Такого не может быть (за исключением ситуации описанной ниже), если нет ошибок в коде SQL Server-а отвечающего за параллельную обработку данных, во что я признаться не верю.

AP>не ошибается только тот кто ничего не делает


Вобще конечно эта фраза здесь как: "не пришей к п...е рукав". Что конкретно ты хотел сказать? Вобще-то совсем непонятно.
Re[7]: Блокировка записей в SQL
От: Merle Австрия http://rsdn.ru
Дата: 13.10.05 08:46
Оценка:
Здравствуйте, AvPyrozhenko, Вы писали:

M>>Там есть две транзакции, одна запущена до начала выборки, другая после. И обе вызывают блокировку выборки.

AP>это я заметил, почему и написал что возможно вы не поняли ситуацию.
Пример иллюстрирует именно описанную ситуацию. Первая транзакция, запущенная до выборки тормозит выборку, чтобы была возможность второй транзакции запуститься после выборки.

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

AP>не ошибается только тот кто ничего не делает

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

AP>как можно объяснить следуещее (моделирование проводил на 100к записей, менял последнию)

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

AP>select при установках по умолчанию возвращает первичные данные.

AP>select в транзакции с uncomited возвращает уже измененные даные.
В первом случае транзакция стартовала после прохождения select-а по нужной записи во втором до, других вариантов быть не может.
Я уже приводил пример где показано как все работает, 100 тыс. записей не надо (тем более что их тоже можно выбрать достаточно шустро), достаточно притормозить селект, чтобы успеть запустить вторую транзакцию и все сразу станет видно.
У MSSQL2000 просто не существует соответствующих механизмов по извлечению предыдущего значения, либо блокировка (и чтение результата после фиксации или отката меняющей транзакции), либо грязные данные — другого не дано.
Мы уже победили, просто это еще не так заметно...
Re[3]: Блокировка записей в SQL
От: Аноним  
Дата: 13.10.05 13:29
Оценка:
Здравствуйте, Igor Trofimov, Вы писали:

C>>Если это простой SELECT в случае Oracle блокировки не будет, т.к. запись не блокирует чтение и наоборот. С другими БД SELECT будет блокирован до тех пор, пока не освободятся нужные данные.


iT>Ну, ну.. не Ораклом единым

iT>Есть и другие БД, не блокирующие читателей.

Вот вот, можно на этом поподробнее, какие еще (из известных публике). И еще, кто знает как работает DB2 с этим? (Читать доку лениво, так как просто спортивный интерес), но была одна история: select * from t в первой сессии, был заблокирован update t set f=3 во второй. Но все бы ничего, но "убив" символом креста вторую сессию, первая так и не ожила, и висела еще 2 часа. Убил и ее, ушел на выходные и в понедельник утром обнаружил в базе 2 активные сессии (да да, те самые) блокирующие таблицу все выходные, в итоге убил уже правильно, средствами БД вторую сессию с этим злосчастным апдейтом. Вопрос в том — либо я криворукий базу неправильно настроил (в визардах плохо Next нажимал), либо такой подход к блокированию принят и в DB2.

И вообще, как можно блокировать чтение, это же маразм.
Re[7]: Блокировка записей в SQL
От: Козьма Прутков Россия  
Дата: 13.10.05 14:01
Оценка:
AP>как можно объяснить следуещее (моделирование проводил на 100к записей, менял последнию)
AP>select при установках по умолчанию возвращает первичные данные.
AP>select в транзакции с uncomited возвращает уже измененные даные.
Контр-пример. 500к записей,
T1
select * from dbo.fiztax2004 where Comments like '%5%' -- это скан таблицы


T2
begin tran
update dbo.fiztax2004 set Comments = Comments + '___' where ID = 12000000721937


В зависимости от момента запуска 2-й транзакции 1-я блокируется или нет. Соответственно, и с уровнем изоляции read uncommitted результаты будут такие-же, только вместо блокировки будут возвращены либо новые, либо старые данные. Собственно, суть-то проста: SQL2к не хранит версии данных, есть только текущая копия и transaction log со старыми данными для определенной транзакции. Соответственно, если я запускаю T1, затем бегу запускаю T2, она обновляет некую запись (и ставит соответствующую блокировку), и после этого T1 подходит к ее анализу (ну, надо как минимум выяснить, like-то соответствует). При этом выполнение T1 приостанавливается (ну, не понятно, как быть, читать неподтвержденные данные невелено) и ждет окончания T2. После этого продолжает свою работу.
Да хранит вас господь в сухом прохладном месте...
Re[4]: Блокировка записей в SQL
От: chabster Украина chabster.blogspot.com
Дата: 13.10.05 14:09
Оценка: :)
> И еще, кто знает как работает DB2 с этим? (Читать доку лениво, так как просто спортивный интерес)

SQLServer отпачковался от DB2 так и работает.
Posted via RSDN NNTP Server 1.9
Re[5]: Блокировка записей в SQL
От: Alex.Che  
Дата: 13.10.05 14:26
Оценка: :)
Привет, chabster!
Вы пишешь 13 октября 2005:

>> И еще, кто знает как работает DB2 с этим?

>> (Читать доку лениво, так как просто спортивный интерес)

c> SQLServer отпачковался от DB2 так и работает.


Во-первЫх, неверно.
Во-втОрых, что есть "отпАчковался" ?

--
With best regards, Alex Cherednichenko.
Posted via RSDN NNTP Server 1.9
Re[4]: Блокировка записей в SQL
От: Merle Австрия http://rsdn.ru
Дата: 13.10.05 14:53
Оценка: +1
Здравствуйте, <Аноним>, Вы писали:

А>Вот вот, можно на этом поподробнее, какие еще (из известных публике).

Interbase, Postgree...

А>И еще, кто знает как работает DB2 с этим?

DB2 классический блокировочник, как и MSSQL 2000. Поведение, соответственно, полностью аналогичное — никаких предыдущих версий для него не существует.

А>И вообще, как можно блокировать чтение, это же маразм.

Маразм — это подозревать в маразме других, самому в вопросе не разобравшись.
... << RSDN@Home 1.1.4 beta 7 rev. 0>>
Мы уже победили, просто это еще не так заметно...
Re[5]: Блокировка записей в SQL
От: chabster Украина chabster.blogspot.com
Дата: 13.10.05 15:04
Оценка: :)
> Маразм — это подозревать в маразме других, самому в вопросе не разобравшись.

Вы явно его подозреваете
Posted via RSDN NNTP Server 1.9
Re[5]: Блокировка записей в SQL
От: Mikst  
Дата: 17.10.05 12:23
Оценка:
Здравствуйте, Merle, Вы писали:

M>Здравствуйте, <Аноним>, Вы писали:


А>>Вот вот, можно на этом поподробнее, какие еще (из известных публике).

M>Interbase, Postgree...

Спасибо, буду знать.

А>>И еще, кто знает как работает DB2 с этим?

M>DB2 классический блокировочник, как и MSSQL 2000. Поведение, соответственно, полностью аналогичное — никаких предыдущих версий для него не существует.

Печально...

А>>И вообще, как можно блокировать чтение, это же маразм.

M>Маразм — это подозревать в маразме других, самому в вопросе не разобравшись.

Ну и что же хорошего в блокировках чтений?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.