【问题标题】:LINQ to SQL: Concurrency resolutionLINQ to SQL:并发解析
【发布时间】:2009-07-23 20:34:53
【问题描述】:

鉴于此 LINQ to SQL:

using (var db = Database.Context)
{
    var root = (from post in db.Post
                where post.Id == rootPostId
                select post).Single();

    root.LastActivityUtc = DateTime.UtcNow;

    db.SubmitChanges();
}

如果同一记录同时被另一个调用具有相同 rootPostId 的同一方法(此代码所在的位置)更改,会发生什么情况?会抛出异常吗?

在这样的事件中——并发冲突——我想通过简单地丢弃更改来处理它,以便只提交一个对 LastActivityUtc 的更新而不是同时提交两个更新,这可能无论如何都具有相同的值。

【问题讨论】:

    标签: sql linq


    【解决方案1】:

    您可以通过发送ChangeConflictException 来检测并解决并发问题:

    using (var db = new MyDataContext())
    {
        var root = (from post in db.Post
                    where post.Id == rootPostId
                    select post).Single();
    
        root.LastActivityUtc = DateTime.UtcNow;
    
        try
        {
            db.SubmitChanges();
        }
        catch (ChangeConflictException)
        {
            db.ChangeConflicts.ResolveAll(RefreshMode.KeepChanges);
            db.SubmitChanges();
        }
    }
    

    使用RefreshMode.KeepChanges,您将保留客户端对象的所有更改,并合并其他用户对其他字段的更改。

    推荐文章:

    【讨论】:

      【解决方案2】:

      这似乎是存储过程的理想选择。与其选择/更新,不如创建一个执行以下操作的简单存储过程:

      UPDATE Post SET LastActivityUtc = GETUTCDATE() WHERE Id=@id

      将 id 传递给存储过程,并在您想要更新帖子的最后一个活动时调用它。

      【讨论】:

      • 至少对我而言,使用 LINQ to SQL 的全部意义在于避免创建存储过程。我没有使用 VS 的 Architect Edition,所以我宁愿不打开 SQL Management Studio。来吧,叫我懒惰。 :)
      • 好吧,你很懒。我也不是存储过程的忠实拥护者,但它们有自己的位置,而这种快速更改正是它们的优势所在。为工作使用正确的工具。 LINQ to SQL 是一把非常大的锤子。并非一切都是钉子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多