Я слежу за онлайн-уроками по транзакциям в соответствии с концепцией ACID. У меня есть две таблицы:
-- Create Product table
CREATE TABLE Product
(
ProductId INT PRIMARY KEY,
Name VARCHAR(50),
Price INT,
Quantity INT
)
GO
-- Populate the Product Table with some test data
INSERT INTO Product VALUES(101, 'Laptop', 1234, 100)
INSERT INTO Product VALUES(102, 'Desktop', 3456, 150)
INSERT INTO Product VALUES(103, 'Tablet', 5678, 200)
INSERT INTO Product VALUES(104, 'Mobile', 7890, 250)
GO
-- Create ProductSales table
CREATE TABLE ProductSales
(
ProductSalesId INT PRIMARY KEY,
ProductId INT,
QuantitySold INT
)
GO
Я создал хранимую процедуру с транзакцией, в которой я предоставляю productId и количество для продажи.
Это моя хранимая процедура:
CREATE PROCEDURE spSellProduct
@ProductID INT,
@QuantityToSell INT
AS
BEGIN
-- First we need to Check the stock available for the product we want to sell
DECLARE @StockAvailable INT
SELECT @StockAvailable = Quantity
FROM Product
WHERE ProductId = @ProductId
-- We need to throw an error to the calling application
-- if the stock is less than the quantity we want to sell
IF(@StockAvailable< @QuantityToSell)
BEGIN
Raiserror('Enough Stock is not available',16,1)
END
-- If enough stock is available
ELSE
BEGIN
BEGIN TRY
-- We need to start the transaction
BEGIN TRANSACTION
-- First we need to reduce the quantity available
UPDATE Product SET
Quantity = (Quantity - @QuantityToSell)
WHERE ProductID = @ProductID
-- Calculate MAX ProductSalesId
DECLARE @MaxProductSalesId INT
SELECT @MaxProductSalesId = CASE
WHEN MAX(ProductSalesId) IS NULL THEN 0
ELSE MAX(ProductSalesId)
END
FROM ProductSales
-- Increment @MaxProductSalesId by 1, so we don't get a primary key violation
Set @MaxProductSalesId = @MaxProductSalesId + 1
-- We need to insert the quantity sold into the ProductSales table
INSERT INTO ProductSales(ProductSalesId, ProductId, QuantitySold)
VALUES(@MaxProductSalesId, @ProductId, @QuantityToSell)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SELECT ERROR_NUMBER() as ErrorNumber,
ERROR_MESSAGE() as ErrorMessage,
ERROR_PROCEDURE() as ErrorProcedure,
ERROR_STATE() as ErrorState,
ERROR_SEVERITY() as ErrorSeverity,
ERROR_LINE() as ErrorLine
END CATCH
End
END
go
spSellProduct @ProductId=103, @QuantityToSell=300
Я проверяю, если количество меньше количества для продажи, тогда я выдаю ошибку. Если ошибок не обнаружено, я начинаю транзакцию.
Затем вычитаю количество из таблицы продуктов. После этого я увеличиваю ProductSalesId в таблице productSales и вставляю новую строку с ProductId и QuantitySold.
Если возникли какие-либо ошибки, я пытаюсь обработать их в моем пакете перехвата и откатить транзакцию.
Итак в моей таблице Product для ProductId 103, в котором имеется 200 штук, и я выполняю хранимую процедуру c следующим образом:
spSellProduct @ ProductId = 103, @ QuantityToSell = 300
Нет генерируются ошибки, и транзакция не откатывается, если @QuantityToSell больше количества. В этом случае количество для ProductId равно 200, а количество, которое я пытаюсь продать, составляет 300.
Что я здесь не так делаю?
спасибо