Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Блокировка записей на чтение.  [new]
rigor mortis
Member

Откуда:
Сообщений: 72
Привет,
что-то не могу найти решение. Есть таблица, из неё могут читать одновременно несколько транзакций. Допустим во всех транзакциях выполняется

select top(10) * from table1


Так вот надо чтобы каждая транзакция пропускала те строки, которые в данный момент попали в выборку других транзакций (которые ещё не закоммичены). То есть если одна транзакция выбрала свой top(10) записей то она их блокирует таким образом что другие транзакции их пропускают, выбирая свой top(10).
Такое возможно вообще?
11 дек 19, 22:13    [22038174]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
rigor mortis,

WITH (READPAST)

Только с изоляцией снапшотов будут проблемы.
11 дек 19, 23:38    [22038217]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
Gerros
Member

Откуда: Харьков
Сообщений: 501
rigor mortis,

делайте апдейт, а потом уже селект.
12 дек 19, 04:46    [22038261]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
rigor mortis,

select top(10) * from table1 with (updlock, readpast)
12 дек 19, 10:02    [22038388]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
Gerros
Member

Откуда: Харьков
Сообщений: 501
invm,

а где holdlock, begin tran, commit?
13 дек 19, 02:37    [22039295]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
Gerros
а где holdlock, begin tran, commit?
Holdlock зачем?
А где begin tran и commit - спрашивайте у ТС
13 дек 19, 11:37    [22039515]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
rigor mortis
Member

Откуда:
Сообщений: 72
Gerros, да, я тоже к этому пришёл, спасибо.
13 дек 19, 22:09    [22040270]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
rigor mortis
Member

Откуда:
Сообщений: 72
Mind
rigor mortis,

WITH (READPAST)

Только с изоляцией снапшотов будут проблемы.


поясните пожалуйста что за снапшоты?
13 дек 19, 22:10    [22040271]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1172
rigor mortis
Mind
rigor mortis,

WITH (READPAST)

Только с изоляцией снапшотов будут проблемы.


поясните пожалуйста что за снапшоты?


уровень изоляции моментальных снимков. READPAST работает только на уровнях READ COMMITTED и REPEATABLE READ.
подробнее можете прочитать в справке.
13 дек 19, 22:35    [22040280]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
rigor mortis
да, я тоже к этому пришёл, спасибо.
Правильно. Пускай конкурирующие транзакции ждут.
Да и про update в условиях ни слова. И как потом прочитать ровно то, что было проапдейчено тоже не важно.

Вообще, при таком раскладе, делают примерно так:
update top (...) table1 with (readpast)
set ...
output ...
where ...
13 дек 19, 23:11    [22040289]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
Gerros
Member

Откуда: Харьков
Сообщений: 501
invm
Вообще, при таком раскладе, делают примерно так:
update top (...) table1 with (readpast)
set ...
output ...
where ...
не уверен, не может случиться что два потока одну и ту же запись обновят по очереди?
по-моему, так надёжней:
declare @this uniqueidentifier = newid()
--быстро забираем себе какую-нибудь запись из очереди
begin tran
update top(...) queue set thread = @this, status = 0 --in progress
where thread = null
  and ...
order by ...
commit

--теперь можно не торопиться
select * from queue where this = @a and status = 0 --результат может быть пустым
...
...
14 дек 19, 02:03    [22040330]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1172
Gerros
invm
Вообще, при таком раскладе, делают примерно так:
update top (...) table1 with (readpast)
set ...
output ...
where ...
не уверен, не может случиться что два потока одну и ту же запись обновят по очереди?
по-моему, так надёжней:
declare @this uniqueidentifier = newid()
--быстро забираем себе какую-нибудь запись из очереди
begin tran
update top(...) queue set thread = @this, status = 0 --in progress
where thread = null
  and ...
order by ...
commit

--теперь можно не торопиться
select * from queue where this = @a and status = 0 --результат может быть пустым
...
...


а где в вашем примере выполнение требования которое хотел ТС? у вас сформируется очередь из писателей приэтом блокировки будут неизбежны.
14 дек 19, 04:34    [22040339]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
Gerros
не уверен, не может случиться что два потока одну и ту же запись обновят по очереди?
Когда все конкурирующие обновлятели с readpast?
Есть репро? Или, хотя бы, сможете объяснить как такое возможно?
14 дек 19, 12:05    [22040384]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
rigor mortis
Member

Откуда:
Сообщений: 72
С обновлением по очереди всё нормально. После обновления в строке устанавливается поле read=true, а обновлять транзакция может только если read=false.
14 дек 19, 12:11    [22040387]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
rigor mortis
С обновлением по очереди всё нормально. После обновления в строке устанавливается поле read=true, а обновлять транзакция может только если read=false.
Интересно, вы хоть понимаете, что все конкурирующие транзакции с таким же действием (set read=true) выстроятся в очередь?
Судя по всему - нет. Иначе давно бы уже потратили пару минут своего драгоценного времени на чтение документации по readpast.
14 дек 19, 13:02    [22040401]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Gerros
invm
Вообще, при таком раскладе, делают примерно так:
update top (...) table1 with (readpast)
set ...
output ...
where ...
не уверен, не может случиться что два потока одну и ту же запись обновят по очереди?
по-моему, так надёжней:
declare @this uniqueidentifier = newid()
--быстро забираем себе какую-нибудь запись из очереди
begin tran
update top(...) queue set thread = @this, status = 0 --in progress
where thread = null
  and ...
order by ...
commit

--теперь можно не торопиться
select * from queue where this = @a and status = 0 --результат может быть пустым
...
...
А если ваша сессия отвалится не закончив обработку? Не изобретайте велосипед.
20 дек 19, 23:23    [22045716]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
entrypoint
Member

Откуда:
Сообщений: 227
Mind
Gerros
пропущено...
не уверен, не может случиться что два потока одну и ту же запись обновят по очереди?
по-моему, так надёжней:
declare @this uniqueidentifier = newid()
--быстро забираем себе какую-нибудь запись из очереди
begin tran
update top(...) queue set thread = @this, status = 0 --in progress
where thread = null 
  and ...
order by ... 
commit

--теперь можно не торопиться
select * from queue where this = @a and status = 0 --результат может быть пустым
...
...
А если ваша сессия отвалится не закончив обработку? Не изобретайте велосипед.



Бреtt

Сообщение было отредактировано: 24 дек 19, 11:01
24 дек 19, 10:58    [22047581]     Ответить | Цитировать Сообщить модератору
 Re: Блокировка записей на чтение.  [new]
entrypoint
Member

Откуда:
Сообщений: 227
Gerros,

where thread = null наверно какие-то специальные настройки нужны, чтобы это работало

order by ... а здесь и настройки не помогут, если это T-SQL - нет такого синтаксиса для контструкции Update


автор
по-моему, так надёжней:

просто очень надежно

Сообщение было отредактировано: 24 дек 19, 11:03
24 дек 19, 11:02    [22047586]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить