首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理单数据库字段的多个更新

处理单数据库字段的多个更新
EN

Stack Overflow用户
提问于 2017-01-06 15:25:12
回答 2查看 52关注 0票数 0

为了给我的问题提供一些背景,我有一个非常基本的银行系统。目前的过程是:

  1. 事务被添加到Azure服务总线
  2. Azure new作业接收此消息并在SQL中创建新行。
  3. 帐户的余额(总计)需要用消息中的值(无论是+还是-)更新。

例如,如果字段为10,我得到两个更新( 10,- 5),字段需要为15 (10 +10-5),这不是只更新值的情况,它需要做一些算术。

现在,我不太确定如何处理余额的更新,因为可能会有许多请求出现,因此需要相应更新。

我认为一种方法是在SQL端进行更新,而不是web作业,但这无助于并发更新。

我能用这个领域做些锁定吗?但是,当由于更新已经在进行中而阻止更新时,更新会发生什么呢?它是等待还是失败?如果它等待,那么这应该是可以的。我在用EF。

我想,另一种方法是让另一个WebJob按计划运行,并将所有的金额加起来并更新一次值,所以这将是唯一接触该字段的东西。

谢谢

EN

回答 2

Stack Overflow用户

发布于 2017-01-06 16:04:19

无论如何,您都需要序列化对account balance字段的写访问(实际上是对整个行)。

有一个单独的作业来获取“挂起”的插入,并最终更新余额将是可以的,以防写在您的系统上比读取更频繁,或者您不必总是返回最近的余额。否则,要获得当前余额,您需要执行以下操作

代码语言:javascript
复制
SELECT balance + 
    ISNULL((SELECT SUM(transaction_amount) 
    FROM pending_insert pi WHERE pi.user_id = ac.user_id
     ),0) as actual_balance
FROM account ac
WHERE ac.user_id = :user_id

从性能的角度来看,这绝对是比较昂贵的,但是对于某些系统来说,这是非常好的。另一个陷阱(同样,它可能与你的情况无关)是强制执行,例如,非负平衡。

或者,您可以以下列方式一贯地处理银行事务:

  1. 开始数据库事务
  2. 在帐户表中查找并锁定行
  3. 如有需要,确认总金额
  4. 将记录插入banking_transaction
  5. 更新用户帐户,即余额=余额+transasction_amount
  6. 提交/rollback 如果涉及多个用户帐户,则必须始终按相同顺序锁定它们,以避免死锁。

这种方法更健壮,但从并发的角度看可能更糟(同样,它取决于应用程序中更新的性质--这里最糟糕的情况是,对一个用户进行多个并发银行交易,对多个用户的更新会很好)。

最后,值得一提的是,由于您使用的是SQLServer,请注意锁升级导致的死锁。无论如何,您可能需要实现一些重试逻辑。

票数 0
EN

Stack Overflow用户

发布于 2017-01-06 16:05:58

您可能希望在sql中使用参数替换方法。您将需要了解如何根据您正在使用的编程语言在您的网络工作。

代码语言:javascript
复制
$updateval = -5;
Update dbtable set myvalue = myvalue + $updateval

code example:
int qn = int.Parse(TextBox3.Text)
SqlCommand cmd1 = new SqlCommand("update product set group1 = group1 + @qn where productname = @productname", con);
cmd1.Parameters.Add(new SqlParameter("@productname", TextBox1.Text));
cmd1.Parameters.Add(new SqlParameter("@qn", qn));

那就执行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41508776

复制
相关文章

相似问题

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