实体框架乐观并发更新存储过程(Julie Lerman的例子)



我在使用Update存储过程理解并发性问题时遇到了一些困难。我遵循Julie Lerman的编程实体框架,她在一个例子中给出了以下代码:

using (var context = new BAEntities())
        {
            var payment = context.Payments.First();
            if (payment.PaymentDate != null)
            {
                payment.PaymentDate = payment.PaymentDate.Value.AddDays(1);
            }
            var origRowVersion = payment.RowVersion;
            try
            { //BREAKPOINT #1
                context.SaveChanges();
                var newRowVersion = payment.RowVersion;
                if (newRowVersion == origRowVersion)
                {
                    Console.WriteLine("RowVersion not updated");
                }
                else
                {
                    Console.WriteLine("RowVersion updated");
                }
            }
            catch (OptimisticConcurrencyException)
            {
                Console.WriteLine("Concurrency Exception was thrown");
            }
        }

更新SP如下:

UPDATE payments
SET paymentdate=@date,reservationID=@reservationID,amount=@amount, modifieddate=@modifiedDate
WHERE
paymentid=@paymentid AND ROWVERSION=@rowversion 
IF @@ROWCOUNT>0
SELECT RowVersion AS newTimeStamp FROM payments WHERE paymentid=@paymentid

和"使用原始值"复选框在映射中被选中,看起来像这样:https://dl.dropboxusercontent.com/u/135754/updatemapping.png

现在,当我尝试:

  1. 按原样运行代码,然后在调试器中检查的newRowVersion与origRowversion相同,但应用程序进入'else'子句(为什么它首先是相同的,我刚刚改变了它?

  2. 运行代码,但在breakpoint# 1中,我更新了Management Studio中的支付对象,SaveChanges抛出了OptimisticConcurrencyException。

每次当我查看SQL Profiler时,原始版本的时间戳都被发送到服务器。

然后,当我在SP映射中为时间戳值勾选"使用原始值"时,一切都以上述方式工作…我不明白这是怎么回事。我测试错了吗?什么时候应用程序应该进入'if'子句?

提前感谢,干杯!

编辑:我添加了newTimeStamp作为Update SP映射的返回值。现在我可以看到RowVersion的更新值正确地从DB中获取。但是我还是看不出选中"Use original value"和不选中"Use original value"有什么区别。

我想我现在明白了。当我尝试在调用savechanges之前手动更改rowversion(为随机字节[])时:

  1. 使用未检查的原始值:'随机字节[]'被发送到DB并在更新存储过程中使用(在WHERE子句中),导致OptimisticConcurrencyException
  2. 使用原始值检查:rowversion最初从DB下载时的值被发送并用于更新存储过程(在WHERE子句中)

我猜这就是使用原始值的目的…这对我来说有点奇怪,谁会在同一个上下文中手动更改它?

最新更新