首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理这个数据并发问题?

如何处理这个数据并发问题?
EN

Stack Overflow用户
提问于 2011-07-20 14:22:11
回答 2查看 678关注 0票数 1

我正在做一个金融应用程序,在这个应用程序中,我预计会出现数据并发问题。

假设有一个帐户ABC,其中有500美元。网络用户可以将这些资金转移到其他账户。这将包括两个步骤,第一步检查资金的可用性,第二步转移。我正在进行一个事务,并在其中执行这两个操作。

问题是,在一段时间内(比如Time1)有2到3个独立的请求(比如transaction1、transaction2、transaction3)传输相同的金额。现在承诺的可用金额为500美元。如果所有的翻译都在同一时间开始,那么所有的测试都是可用的($500)吗?这将是真的,下一条语句将把资金转移到其他账户。

我读过关于事务隔离级别的文章,但我不能决定我应该使用哪个隔离级别,实际上我对它的理解是混乱的。请帮帮我。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-20 14:26:05

这样做的目的是防止另一个进程读取余额,但最小化对其他用户的阻塞。所以使用"table as a queue“类型的锁如下所示:

代码语言:javascript
复制
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

另一种方法是在一个表中完成,如果只涉及一个表,这种方法更可行。交叉连接是对以下各项的测试

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2011-07-20 14:32:47

为了避免提取大于价格的金额,您可以这样做:

代码语言:javascript
复制
update <table> 
set amount = amount - @price
where amount >= @price
and account = @account

if @@rowcount = 1 print 'transaction went well' else print 'Insufficient funds'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6757787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档