【问题标题】:SQL Optimistic Concurrency - Involving several tables across dbSQL Optimistic Concurrency - 涉及跨数据库的多个表
【发布时间】:2017-05-28 10:50:31
【问题描述】:

想象一下我们有 Products 表的场景,我们在其中定义 ProductId、Name、Price。 此外,我们还有 InvoicesHeader 和 InvoicesLines 表,当用户创建 Invoices 并向其中添加项目时,它们会被填充。

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

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

  1. userA 开始创建发票并将 ProductX 添加到发票项目。 Products 表中商品的价格已填充
  2. userA 继续添加其他项目
  3. 在用户 A 完成发票(最后一次保存)之前,用户 B 转到 Products 表并更改 ProductX 的价格
  4. userA 现在提交发票

理想的结果是通知用户A(在单击保存发票时)价格发生了变化。 完成此任务的最佳做法是什么?

一种选择是在 Products 表上设置 rowversions/timestamps,将它们带到 UI 并与订单项一起提交回来。所以在保存发票时,事务首先检查lineitems的rowversions和对应的products表记录是否完​​整。如果是 > 继续,如果不是 > 通知用户。 此外,在这种情况下,似乎 SaveInvoices 事务应在产品表行上保持 REPEATABLE_READ 隔离级别,以确保在将项目保存到发票期间不会更改价格。

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

【问题讨论】:

    标签: sql-server tsql locking isolation-level


    【解决方案1】:

    我会在 Product 表中添加 LastValueModifiedDate 日期时间列,并在值更改时更新它。
    因此,在保存发票时:

    如果当前日期时间

    如果当前日期时间 >= 至少一个产品的 LastValueModifiedDate,那么您可以通知用户哪些产品的价值发生了变化。

    【讨论】:

    • 由于几个原因,我非常不愿意使用任何类型的日期时间。有些是:日期时间精度问题、时区、夏令时等......我可以看到一些与日期时间有关的不可预测因素,其中比较可能会出错。如果我错了,请纠正我。
    • 所有日期时间都是 sql server 日期时间(当值更改时,getdate() 应该存储在产品中,并且 getdate() 应该与这个存储的日期进行比较)。没有用户客户端日期时间。
    • 我猜你希望在这种情况下至少有 getutcdate() 。另外,当你的 DST 倒退时会发生什么?
    • 什么意思? “……夏令时倒退……”
    • 如果你有getdate(),当夏令时改变时会发生什么?它会以任何方式影响它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-14
    • 2021-06-05
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多