SQL乐观并发 - 跨数据库

时间:2017-01-13 06:00:37

标签: sql-server tsql locking isolation-level

想象一下我们有Products表的场景,我们定义ProductId,Name,Price。 此外,我们还有InvoicesHeader和InvoicesLines表格,这些表格会在用户创建发票并向其添加商品时填写。

InvoicesLine表通过ItemProductId FK引用Products表,并且该项目的字段价格最初设置为存储在该项目的Products表中的值,但用户在创建发票时可能会更改。

现在,可能会出现这样的情况:

  1. userA开始创建发票并将ProductX添加到发票项目。 “产品”表中的商品价格已填充
  2. userA继续添加其他项目
  3. 在userA完成发票之前(最后一次保存)userB转到Products表并更改ProductX的价格
  4. userA现在提交发票
  5. 理想的结果是用户A被通知(点击保存发票时)价格已更改。 实现这个目标的最佳做法是什么?

    一个选项是在Products表上设置rowversions / timestamps,将它们带到UI并使用订单项将其提交回来。因此,在保存发票时,事务首先检查lineitems和相应的产品表记录的反转是否完好无损。如果是这样的话>继续,如果不是>通知用户。 此外,似乎SaveInvoices事务应该在这种情况下保持产品表行上的REPEATABLE_READ隔离级别,确保在将项目保存到发票期间没有更改价格。

    我想知道是否有更优雅的方式来做这件事,因为这感觉有点麻烦。

1 个答案:

答案 0 :(得分:0)

我会在Product表中添加LastValueModifiedDate datetime列,并在值发生变化时更新它。
因此,在保存发票时:

如果当前日期时间<每个产品的LastValueModifiedDate然后可以保存。

如果至少有一个产品的LastValueModifiedDate的固有日期时间> =那么您可以告知用户哪些产品的值已更改。