我正在做一个财务应用程序,我期待数据并发问题。
假设有一个账户ABC,其中有500美元。来自网络的用户可以将这些资金转移到其他帐户。这将涉及两个步骤,首先检查资金的可用性和第二次转移。我正在做一笔交易并在其中做两件事。
问题是在某个时间(比如Time1)有2或3个seprate转移请求(比如transaction1,transaction2,transaction3)相同的数量。现在承诺的可用金额是500美元。如果所有翻译都在同一时间开始,所有测试的金额(500美元)都可用吗?这将是真实的和下一个声明将资金转移到其他帐户。
我已经阅读了有关事务隔离级别但我无法确定应该使用哪个隔离级别,实际上我对它的理解感到困惑。请帮帮我。
由于
答案 0 :(得分:1)
目的是防止另一个进程读取余额,但最大限度地减少对其他用户的阻止。因此,使用“table as a queue”类型锁定:
SET XACT_ABORT, NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION
SELECT @balance = Balance
FROM SomeTable WITH (ROWLOCK, HOLDLOCK, UPDLOCK)
WHERE Account = 'ABC'
--some checks
UPDATE ...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
...
END CATCH
替代方案是在一个中进行,如果涉及一个表,则更可行。 CROSS JOIN是对
的测试SET XACT_ABORT, NOCOUNT ON;
BEGIN TRY
--BEGIN TRANSACTION
UPDATE SomeTable WITH (ROWLOCK, HOLDLOCK, UPDLOCK)
SET Balance = Balance - @request
WHERE
ST.Account = 'ABC' AND Balance > @request;
IF @@ROWCOUNT <> 1
RAISERROR ('Not enough in account', 16, 1);
--COMMIT TRANSACTION
END TRY
BEGIN CATCH
...
END CATCH
答案 1 :(得分:0)
为了避免提取超过价格的金额,您可以这样做:
update <table>
set amount = amount - @price
where amount >= @price
and account = @account
if @@rowcount = 1 print 'transaction went well' else print 'Insufficient funds'