2015-02-16 4 views
0

Предположим, что у меня есть таблица с полем акций.Обновление - это атомная операция? (обновление запасов)

  • MyTable (ID, Шток, ...)

Если я:

Update Mytable set Stock = stock -5 where ID = 123; 

Является ли запись 123 заблокирован до обновления, так что я могу быть уверен, что запись имеет правильная сумма акций или не является хорошим способом обновления запасов?

Большое спасибо.

+0

Ничего плохого в этом. – DavidG

ответ

1

Существует раздвижная шкала между параллелизмом и изоляцией. Чем больше вы получаете, тем меньше вы получаете от другого. Таким образом, вы можете сделать что-то вроде этого:

DECLARE @Stock int; 
BEGIN TRAN 

SELECT @Stock=Stock 
FROM dbo.MyTable 
WHERE ID = 123 
WITH (UPDLOCK); --lock the row for update 

--inspect @Stock to make sure it's what you're expecting 

UPDATE dbo.MyTable 
SET Stock = Stock - 5 
WHERE ID = 123; 

COMMIT TRAN 

Недостатком является то, что кто-то пытается прочитать строку, пока есть транзакция активна. Но это также гарантирует, что никто не будет обновлять строку до значения, отличного от того, что вы думаете.

+0

действительно подсказка UPDLOCK блокирует строку в списке? Потому что я попробовал другие подсказки, и есть случаи, когда строка не заблокирована, хотя и ожидается. Единственный способ, которым я нахожу работу, - сделать первое обновление внутри транзакции для блокировки. Спасибо большое. –

+0

Я должен был быть более ясным; другие запросы, указывающие UPDLOCK, будут заблокированы. Подумайте об этом таким образом, в большинстве случаев вы не хотите блокировать выбор из чтения значения из таблицы, поскольку это серьезно затруднит параллелизм. Вместо этого вы просто хотите узнать, что, когда вы собираетесь обновить значение, оно не изменилось из-под вас. Итак, если вы делаете что-то вроде выше (оберните его в процедуру, возможно?), У вас будет возможность проверить значение и, возможно, прервать обновление, если это не то, что вы ожидаете. –

Смежные вопросы