为了给我的问题提供一些背景,我有一个非常基本的银行系统。目前的过程是:
例如,如果字段为10,我得到两个更新( 10,- 5),字段需要为15 (10 +10-5),这不是只更新值的情况,它需要做一些算术。
现在,我不太确定如何处理余额的更新,因为可能会有许多请求出现,因此需要相应更新。
我认为一种方法是在SQL端进行更新,而不是web作业,但这无助于并发更新。
我能用这个领域做些锁定吗?但是,当由于更新已经在进行中而阻止更新时,更新会发生什么呢?它是等待还是失败?如果它等待,那么这应该是可以的。我在用EF。
我想,另一种方法是让另一个WebJob按计划运行,并将所有的金额加起来并更新一次值,所以这将是唯一接触该字段的东西。
谢谢
发布于 2017-01-06 16:04:19
无论如何,您都需要序列化对account balance字段的写访问(实际上是对整个行)。
有一个单独的作业来获取“挂起”的插入,并最终更新余额将是可以的,以防写在您的系统上比读取更频繁,或者您不必总是返回最近的余额。否则,要获得当前余额,您需要执行以下操作
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从性能的角度来看,这绝对是比较昂贵的,但是对于某些系统来说,这是非常好的。另一个陷阱(同样,它可能与你的情况无关)是强制执行,例如,非负平衡。
或者,您可以以下列方式一贯地处理银行事务:
这种方法更健壮,但从并发的角度看可能更糟(同样,它取决于应用程序中更新的性质--这里最糟糕的情况是,对一个用户进行多个并发银行交易,对多个用户的更新会很好)。
最后,值得一提的是,由于您使用的是SQLServer,请注意锁升级导致的死锁。无论如何,您可能需要实现一些重试逻辑。
发布于 2017-01-06 16:05:58
您可能希望在sql中使用参数替换方法。您将需要了解如何根据您正在使用的编程语言在您的网络工作。
$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));那就执行。
https://stackoverflow.com/questions/41508776
复制相似问题