2010-06-24 64 views
0

我理解编辑行如何导致并发问题,但选择行导致的并发问题是我不明白的。线程安全“选择”Linq查询?

如果查询从数据库选择数据,并发问题如何产生?是否如果对我选择的数据进行了更改,事情会爆炸?

在任何情况下,如果由选择查询引起的并发问题,处理它的最佳方法是什么?这是我的想法,但如果它错了,我一点也不会感到惊讶。

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

回答

0

在这种情况下,您的选择操作本质上等于读取/查询。即使只读操作也会导致应用程序出现并发问题。

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

处理并发问题的最好方法是简单地避免它。如果你有2个线程玩同一个数据使用一个锁来串行访问数据是可能是最好的办法。虽然一个明确的解决方案需要更多的细节。

你能解释一下这里发生了什么,为什么这场比赛正在发生?其他线程在阅读时是否修改此对象?

0

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

查看您的示例,更重要的一点是您放入try/catch块的代码实际上并没有执行任何查询。它只是建立一个表达式树。在你做一些事情导致表达式树被评估之前,SQL查询将不会被运行,就像调用SelectQuery.ToList()一样。

请记住,当您尝试查询数据库时,有很多事情可能“出错”。也许有人正在对您尝试选择的数据进行大量更新,并且在完成查询之前连接超时。也许电缆被碰撞,或者随机的一点宇宙辐射导致某处丢失。然后再次,也许你的查询有问题,或者你正在使用的数据库上下文没有同步到数据库模式。一些可能出错的事情只是间歇性的,你可以像你的问题一样再试一次。其他事情可能会更持久,并会不断重复。对于后面的情况,如果你试图重复你的行动直到你不再犯错,你的线程可能会在那里停留很长时间。

因此,当您决定如何处理数据库连接问题时,请注意您希望发生各种问题的频率。我看到了在放弃之前尝试执行三次交易的代码,like this。但是当涉及到日常查询时,这种情况很少发生,我个人只会允许异常涓涓细流到用户界面可以说“出现意外错误,请再试一次,如果问题仍然存在,请联系你的管理员。“或类似的东西。