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

Есть транзакция, в ней выпоняются след. действия
1. Проверка товара на складе (есть такое наименование или нет)
2. Если товар есть то 3 если нет то 4
3. Обновить количество
4. Вставить наименование и кол-во товара.

Проверка происходит так
Declare @Qty int;
SET @Qty = -1;

SELECT @Qty = qty FROM Wirehouse WHERE good_id = @good_id;

IF (@Qty = -1)
   INSERT INTO Wirehouse VALUES(@good_id, @Quantity)
ELSE
  UPDATE Wirehouse SET qty = @Quantity + @Qty;


Вопрос: Не может ли вклинится кака нибудь транзакция между SELECTом и INSERTом и вставить запись. Если нет, то почему?
11 ноя 05, 13:09    [2059856]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17091
https://www.sql.ru/faq/faq_topic.aspx?fid=493
11 ноя 05, 13:10    [2059867]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Демиург
Member

Откуда:
Сообщений: 203
ScareCrow
Я читал про транзакции
11 ноя 05, 13:19    [2059923]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Демиург
Member

Откуда:
Сообщений: 203
Знаю, что то о чем я говорю - Фантомы
Мне интересно на практите (мой случай) такое будет иметь место или нет??
11 ноя 05, 13:20    [2059926]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Glory
Member

Откуда:
Сообщений: 104760
Демиург
Знаю, что то о чем я говорю - Фантомы
Мне интересно на практите (мой случай) такое будет иметь место или нет??

Ну так поставьте после SELECT-а задержку и посмотрите, что сможет сделать с таблицей второй коннект
11 ноя 05, 13:25    [2059947]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
ScareCrow
Member

Откуда: Белый город
Сообщений: 17091
автор
Фиктивные элементы (фантомы)
Эффект фиктивных элементов несколько отличается от предыдущих транзакций тем, что здесь за один шаг выполняется достаточно много операций - чтение одновременно нескольких строк, удовлетворяющих некоторому условию.

Транзакция A дважды выполняет выборку строк с одним и тем же условием. Между выборками вклинивается транзакция B, которая добавляет новую строку, удовлетворяющую условию отбора.

11 ноя 05, 13:25    [2059949]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Ray D
Member

Откуда: from the middle of nowhere
Сообщений: 3598
Блог
ну а почему нет, запросто. уровень изоляции read committed?
11 ноя 05, 13:26    [2059958]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Демиург
Member

Откуда:
Сообщений: 203
Да
Вот я и думаю поставить наверно надо SERIALIZABLE

Вот и спросил совета

2 ScareCrow
и что?
Я прочитал
SELECT @Qty = qty FROM Wirehouse WHERE good_id = @good_id;

Нету такой строки - @Qty остался =-1

В этот момент кто то влезает и добавляет строку удов. данному условию, вот и фантом
11 ноя 05, 13:33    [2060008]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Glory
Member

Откуда:
Сообщений: 104760
Тогда уж
UPDATE Wirehouse SET qty = @Quantity + @Qty;
IF @@ROWCOUNT = 0 INSERT INTO Wirehouse VALUES(@good_id, @Quantity)

c добавлением UQ constraint на good_id и обработкой ошибке его нарушения
11 ноя 05, 13:36    [2060033]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Glory
Member

Откуда:
Сообщений: 104760
UPDATE Wirehouse SET qty = @Quantity + @Qty WHERE good_id = @good_id;
IF @@ROWCOUNT = 0 INSERT INTO Wirehouse VALUES(@good_id, @Quantity)
11 ноя 05, 13:39    [2060053]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Glory
Member

Откуда:
Сообщений: 104760
Это если количество добавляемых товаров мало. И стало быть вероятность конфликта тоже мала.
Если все наоборот, то тогда

INSERT INTO Wirehouse 
SELECT @good_id, @Quantity 
WHERE NOT EXISTS(SELECT * FROM Wirehouse (HOLDLOCK) WHERE good_id = @good_id;)
IF @@ROWCOUNT = 0 UPDATE Wirehouse SET qty = @Quantity + @Qty WHERE good_id = @good_id;
11 ноя 05, 13:45    [2060088]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Glory
Member

Откуда:
Сообщений: 104760
Или вообще сделать индекс
create UNIQUE index ix1_Wirehouse on Wirehouse(good_id) with IGNORE_DUP_KEY 

и

INSERT INTO Wirehouse VALUES(@good_id, @Quantity)
IF @@ROWCOUNT = 0 UPDATE Wirehouse SET qty = @Quantity + @Qty WHERE good_id = @good_id;

при любом уровне изоляции
11 ноя 05, 13:50    [2060119]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Aleksey-K
Member

Откуда: Москва
Сообщений: 3116
Если заботит кол-во товара (перерасход), то достаточно REPEATABLE READ (или Hint HOLDLOCK) при чтении кол-во. При этом SELECT... после BEGIN TRANSACTON. Зачем для этого SERIALIZABLE ?
С уважением, Алексей.
11 ноя 05, 14:00    [2060194]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
Демиург
Member

Откуда:
Сообщений: 203
Глори, спасибо
INSERT INTO Wirehouse 
SELECT @good_id, @Quantity 
WHERE NOT EXISTS(SELECT * FROM Wirehouse (HOLDLOCK) WHERE good_id = @good_id;)
IF @@ROWCOUNT = 0 UPDATE Wirehouse SET qty = @Quantity + @Qty WHERE good_id = @good_id;

Этот вариант красив, но ведь практически делает тоже самое, и необходимо блокировать SELECT * FROM Wirehouse (HOLDLOCK) WHERE good_id = @good_id; чтоб не было Фантомов?
И это же решает и уровень SERIALIZABLE

2 Aleksey-K: От фантомов оберегаюсь.
11 ноя 05, 17:36    [2061529]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
funikovyuri
Member

Откуда: Симферополь
Сообщений: 4045
А может UPDLOCK, а не HOLDLOCK?
27 ноя 05, 21:51    [2114458]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
aleks2
Guest
Демиург


2 Aleksey-K: От фантомов оберегаюсь.


От фантомов гарантию дает только уникальный INDEX или CONSTRAINT на таблице. Причем не возбраняется проводить доп. проверки чтобы избежать "лишних" сообщений об ошибках.
----------------------
А хинты - отстой.
28 ноя 05, 06:28    [2114656]     Ответить | Цитировать Сообщить модератору
 Re: Уровень изоляции  [new]
funikovyuri
Member

Откуда: Симферополь
Сообщений: 4045
aleks2
----------------------
А хинты - отстой.


Это вы про updlock?
28 ноя 05, 13:58    [2116242]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить