Se alguém executa o procedimento armazenado abaixo muito rápido (alguns milhares de execução por segundo), a variável @amount pode mudar durante a execução e executar a atualização mais de uma vez?
CREATE PROCEDURE [dbo].[PayoutInvestment]
@userid AS VARCHAR(50)
,@idi AS INT
AS
BEGIN
BEGIN TRANSACTION;
DECLARE @amount AS DECIMAL(18, 2) = (
SELECT amount
FROM investments
WHERE userid = @userid
AND idi = @idi
AND date_stop IS NULL
);
IF (@amount IS NOT NULL)
BEGIN
UPDATE investments
SET date_stop = GETUTCDATE()
WHERE idi = @idi;
UPDATE u
SET balance = u.balance + @amount
FROM users u
INNER JOIN investments i ON u.userid = i.userid
WHERE i.idi = @idi;
END;
COMMIT TRANSACTION;
END
Eu sei que funciona 100% se eu fizer isso com dica de updlock. Mas gostaria de saber se é necessário fazer dessa forma.
CREATE PROCEDURE [dbo].[PayoutInvestment]
@userid AS VARCHAR(50)
,@idi AS INT
AS
BEGIN
BEGIN TRANSACTION;
DECLARE @amount AS DECIMAL(18, 2) = (
SELECT amount
FROM investments WITH (
ROWLOCK
,UPDLOCK
)
WHERE userid = @userid
AND idi = @idi
AND date_stop IS NULL
);
IF (@amount IS NOT NULL)
BEGIN
UPDATE investments
SET date_stop = GETUTCDATE()
WHERE idi = @idi;
UPDATE u
SET balance = u.balance + @amount
FROM users u
INNER JOIN investments i ON u.userid = i.userid
WHERE i.idi = @idi;
END
COMMIT TRANSACTION;
END
Estou usando o nível de isolamento Read Committed.