【问题标题】:Thread Safing "Select" Linq Queries?线程安全“选择”Linq 查询?
【发布时间】:2010-06-24 20:49:37
【问题描述】:

我了解编辑行会如何导致并发问题,但我不明白由选择行引起的并发问题。

如果查询从数据库中选择数据,怎么会出现并发问题?如果对我选择的数据进行更改,事情会不会爆炸?

无论如何,如果存在由选择查询引起的并发问题,最好的处理方法是什么?这是我的想法,但如果它是错误的,我一点也不感到惊讶。

try
{
    var SelectQuery = 
    from a DB.Table
    where a.Value == 1
    select new {Result = a};
}
catch 
{
    //retry query??
}

【问题讨论】:

    标签: c# linq concurrency


    【解决方案1】:

    在这种情况下,您的选择操作基本上相当于读取/查询。即使是只读操作也可能导致应用程序中的并发问题。

    最简单的例子是当正在读取的对象具有线程关联性并且读取发生在不同的线程中时。这可能会导致争用,因为数据的访问方式不正确。

    处理并发问题的最佳方法是简单地避免它。如果您有 2 个线程处理相同的数据,使用锁来序列化对数据的访问可能是最好的方法。虽然最终的解决方案需要更多细节。

    你能解释一下这里发生了什么以及为什么会发生比赛吗?其他线程是否在您读取此对象时对其进行了修改?

    【讨论】:

      【解决方案2】:

      当您的查询运行时,将生成一个与您的查询相对应的 SQL 查询。如果其他线程(或其他任何线程)试图修改您的查询中涉及的表,数据库服务器通常会检测到这一点并处理必要的逻辑以防止它引起任何实际问题。如果您的查询不断与更新语句碰撞,则执行查询可能需要更长的时间,但唯一真正的问题是如果系统检测到正在运行的事务的某种组合实际上导致了死锁。在这种情况下,它将终止其中一个连接。我相信只有当你的语句试图更新数据库值时才会发生这种情况——而不是来自选择。

      查看您的示例,更重要的一点是,您放入 try/catch 块中的代码实际上并没有进行任何查询。它只是构建一个表达式树。 SQL 查询实际上不会运行,除非您执行了导致计算此表达式树的操作,例如调用 SelectQuery.ToList()

      请记住,当您尝试查询数据库时,有很多事情可能会“出错”。也许有人正在对您尝试选择的数据进行大量更新,并且您的连接在完成查询之前就超时了。也许电缆被撞到了,或者随机的一点宇宙辐射导致某个地方迷路了。再说一次,也许您的查询有问题,或者您正在使用的数据库上下文未同步到数据库模式。一些可能出错的事情只是间歇性的,你可以像你的问题建议的那样再试一次。其他事情可能会更持久,并且会不断重复。对于后一种情况,如果您尝试重复您的操作直到不再出现错误,您的线程可能会挂在那里很长时间。

      因此,当您决定如何处理数据库连接问题时,请注意您预计每种问题发生的频率。我看到代码在放弃之前尝试运行事务三次,like this。但是当涉及到日常查询时,这种事情很少发生,我个人只会允许异常蔓延到用户界面可以说“出现意外错误。请重试。如果问题仍然存在,请联系你的管理员。”或者类似的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-03
        • 1970-01-01
        相关资源
        最近更新 更多