我正在做一个金融应用程序,在这个应用程序中,我预计会出现数据并发问题。
假设有一个帐户ABC,其中有500美元。网络用户可以将这些资金转移到其他账户。这将包括两个步骤,第一步检查资金的可用性,第二步转移。我正在进行一个事务,并在其中执行这两个操作。
问题是,在一段时间内(比如Time1)有2到3个独立的请求(比如transaction1、transaction2、transaction3)传输相同的金额。现在承诺的可用金额为500美元。如果所有的翻译都在同一时间开始,那么所有的测试都是可用的($500)吗?这将是真的,下一条语句将把资金转移到其他账户。
我读过关于事务隔离级别的文章,但我不能决定我应该使用哪个隔离级别,实际上我对它的理解是混乱的。请帮帮我。
谢谢
发布于 2011-07-20 14:26:05
这样做的目的是防止另一个进程读取余额,但最小化对其他用户的阻塞。所以使用"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另一种方法是在一个表中完成,如果只涉及一个表,这种方法更可行。交叉连接是对以下各项的测试
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发布于 2011-07-20 14:32:47
为了避免提取大于价格的金额,您可以这样做:
update <table>
set amount = amount - @price
where amount >= @price
and account = @account
if @@rowcount = 1 print 'transaction went well' else print 'Insufficient funds'https://stackoverflow.com/questions/6757787
复制相似问题