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

Откуда:
Сообщений: 186
Впервые столкнулся с подобной задачей.
Нужно выбрать запись из таблицы(SELECT TOP 1), если она есть, то заблокировать и сделать ее обновление, в случае успеха вернуть значение одного поля, в тоже время, если кто-то будет делать выборку из той же таблицы не смог ее выбрать(запись, только другие, соотетствующие этому условию)
14 май 19, 11:42    [21884211]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6221
sc2r2bey,
updlock, readpast
14 май 19, 11:46    [21884213]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
вы имеете ввиду, что нужно так сделать?
BEGIN TRAN

  select top 1 COMMAND
  from EXAMPLE_TABLE
  with (UPDLOCK, ROWLOCK)
  where PROCESSED=false;

ROLLBACK
BEGIN TRANSACTION

      UPDATE TOP(1) EXAMPLE_TABLE
      SET colum1 = colum1 + 1
14 май 19, 12:03    [21884240]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
ошибочка, тупо из примера взял

with (UPDLOCK, READPAST)
14 май 19, 12:04    [21884242]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6221
sc2r2bey,

https://www.mssqltips.com/sqlservertip/1257/processing-data-queues-in-sql-server-with-readpast-and-updlock/
14 май 19, 12:06    [21884246]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28333
sc2r2bey
Впервые столкнулся с подобной задачей.
Нужно выбрать запись из таблицы(SELECT TOP 1), если она есть, то заблокировать и сделать ее обновление, в случае успеха вернуть значение одного поля, в тоже время, если кто-то будет делать выборку из той же таблицы не смог ее выбрать(запись, только другие, соотетствующие этому условию)
Ээээ, а почему нельзя просто сделать один UPDATE с такой функциональностью?
14 май 19, 12:08    [21884250]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
Например?
14 май 19, 12:12    [21884254]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28333
sc2r2bey
Например?
Например, так:
use tempdb
go
create table test(id int identity, a int, b int, condition bit)
go
insert test(a, b, condition) values (1,1,1), (2,2,0)

update test
set b=10
OUTPUT inserted.a
where condition = 1

go
drop table test
Или можно положить OUTPUT в таблицу-переменную, это уже зависит от того, что вы подразумеваете под "вернуть значение одного поля" - нужно, что бы при неуспехе вообще не было выводимого рекордсета, или нужно, что бы он был пустой?
14 май 19, 12:29    [21884282]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28333
alexeyvg
where condition = 1
Тут, конечно, нужно написать правильное условие, соответствующее вашему "Нужно выбрать запись из таблицы(SELECT TOP 1)"; т.к. я его не знаю, то не стал развивать.
14 май 19, 12:30    [21884283]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
спасибо, в принципе более простое решение, мне нужно вернуть значение поля, оно не меняется в процессе запроса
в тразакцию не надо оборачивать, если два таким запроса прилетят одновременно?
14 май 19, 13:01    [21884319]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
TaPaK,
спасибо, хороший материал, а как вернуть мне значение поля выбранной строки?
14 май 19, 13:02    [21884320]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6221
sc2r2bey
TaPaK,
спасибо, хороший материал, а как вернуть мне значение поля выбранной строки?

https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-2017
14 май 19, 13:03    [21884321]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
alexeyvg, и еще момент, если условию будут соответствовать более одной записи?
14 май 19, 13:04    [21884324]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
msLex
Member

Откуда:
Сообщений: 6008
sc2r2bey
alexeyvg, и еще момент, если условию будут соответствовать более одной записи?


update t
...
from (
select top 1 ...
from ...
) t
14 май 19, 13:07    [21884327]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
msLex, разве update top 1 нельзя использовать?
14 май 19, 13:10    [21884329]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6221
sc2r2bey
msLex, разве update top 1 нельзя использовать?

можно
14 май 19, 13:17    [21884342]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
msLex
Member

Откуда:
Сообщений: 6008
sc2r2bey
msLex, разве update top 1 нельзя использовать?


можно, если не нужен order by (приоритет обработки записей)
14 май 19, 13:17    [21884343]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
sc2r2bey
Member

Откуда:
Сообщений: 186
спасибо всем, все оказалось не так сложно, как я боялся )
только какой вариант выбрать? )))
14 май 19, 13:28    [21884356]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28333
sc2r2bey
alexeyvg, и еще момент, если условию будут соответствовать более одной записи?
Я писал, что условие нужно написать такое, что бы соответствовало вашим требованиям. Как тут уже ответили, можно с with, можно с update top 1, можно с подзапросом и джойном, и т.д.
Это всё зависит от ваших требований и модели данных, про которые мы ничего не знаем.
14 май 19, 13:33    [21884366]     Ответить | Цитировать Сообщить модератору
 Re: Как правильно сделать транзакцию и блокировку записи?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28333
sc2r2bey
только какой вариант выбрать? )))
Самый простой и понятный для чтения.
14 май 19, 13:33    [21884367]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить