swanrnd
@swanrnd
Издатель HTML5 игр

Каков лучший вариант транзакции в MS SQL?

Есть 3 таблицы.
1) Пользователь, имеющий деньги.
users: id(int), cash(int(>=0))
пример 10, 1000
Пользователь 10 имеет 1000 рублей. Используем пространственное ограничение cash>0
2) Магазин имеющий товары:
shop: id(int), count
пример: 5, 20
В магазине товаров под номером 5 - 20 штук
3) Покупки пользователя
items: uid(int), item(int), count(int)
пример 10, 5, 3
У пользователя номер 10, 3 штуки товара номер 5.

Задача реализовать покупку товара. Важно 2 вещи:
1) надежно
2) быстро

Варианты:
1)
SET XACT_ABORT ON;
BEGIN TRANSACTION;
UPDATE users SET cash=cash-@price WHERE id=@uid;
UPDATE items SET count=count+1 WHERE uid=@uid and item=@item;
IF @@ROWCOUNT=0
    INSERT INTO items VALUES (@uid, @item, 1);
UPDATE shop SET count=count-1 WHERE item=@item;
COMMIT TRANSACTION;

Здесь основано на ограничениях.

2)
BEGIN TRANSACTION;
UPDATE users SET cash=cash-@price WHERE id=@uid and cash>=@price;
IF @@ROWCOUNT=0
ROLLBACK TRANSACTION;
UPDATE items SET count=count+1 WHERE uid=@uid and item=@item;
IF @@ROWCOUNT=0
    INSERT INTO items VALUES (@uid, @item, 1);
UPDATE shop SET count=count-1 WHERE item=@item;
COMMIT TRANSACTION;

Здесь заложена проверка в UPDATE.

3) Другие варианты?

Хочется услышать аргументированный ответ.
  • Вопрос задан
  • 2454 просмотра
Пригласить эксперта
Ответы на вопрос 1
declare @diff int
      , @count int
select @diff = cash - @price
from users
where id = @uid

select @count = count 
from shop
where item = @item

if (@count>0) and (@diff > 0)
begin
  begin transaction
  update users 
  set cash=cash-@price 
  where id=@uid

  if exists (select top 1 from items where uid = @uid and item=@item)
    update items 
    set count=count+1 
    where uid=@uid and item=@item;
  else
    insert into items 
      select @uid, @item, 1;

  update shop
  set count=count-1 
  where item=@item;

if @@error != 0
  rollback

commit
end
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы