我理解编辑行如何导致并发问题,但选择行引起的并发问题是我无法理解的。
如果查询从数据库中选择数据,如何出现并发问题?如果我选择的数据发生了变化,事情就会爆发吗?
在任何情况下,如果由select查询引起并发问题,处理它的最佳方法是什么?这就是我的想法,但如果它错了,我不会感到惊讶。
try
{
var SelectQuery =
from a DB.Table
where a.Value == 1
select new {Result = a};
}
catch
{
//retry query??
}
答案 0 :(得分:0)
在这种情况下,您的选择操作基本上等于读/查询。即使是只读操作也会导致应用程序出现并发问题。
最简单的示例是当从中读取的对象具有线程亲和性并且从另一个线程发生读取时。由于以不正确的方式访问数据,这可能会导致竞争。
处理并发问题的最佳方法是简单地避免它。如果您有2个线程使用相同的数据,使用锁定序列化访问数据是可能最好的方法。虽然最终解决方案需要更多细节。
你能解释一下这里发生了什么以及比赛发生的原因吗?在阅读时,其他线程是否会修改此对象?
答案 1 :(得分:0)
运行查询时,将生成与您的查询对应的SQL查询。如果其他线程(或其他任何线程)正在尝试修改查询中涉及的表,则数据库服务器通常会检测到这一点并处理必要的逻辑,以防止出现任何实际问题。如果查询继续使用更新语句,则执行查询可能需要更长的时间,但唯一真正的问题是,如果系统检测到某些正在运行的事务的组合实际上导致死锁。在这种情况下,它将杀死其中一个连接。我相信只有当你的语句试图更新数据库值时才会发生这种情况 - 而不是选择。
更重要的一点是,看一下你的例子,你在try / catch块中放入的代码实际上并没有进行任何查询。它只是构建一个表达式树。在您执行导致对此表达式树进行求值的操作之前,实际上不会运行SQL查询,例如调用SelectQuery.ToList()
。
请记住,当您尝试查询数据库时,有许多事情可能“出错”。也许某人正在对您尝试选择的数据进行大量更新,并且在完成查询之前您的连接超时。也许电缆会被碰撞,或者随机的一点宇宙辐射会导致某些地方丢失。然后,也许你的查询有问题,或者你正在使用的数据库上下文没有同步到数据库模式。一些可能出错的事情只是间歇性的,你可以像你的问题所说的那样再试一次。其他事情可能会更持久,并会继续发生。对于后面这些情况,如果您尝试重复操作直到您不再收到错误,那么您的主题可能会在那里停留很长时间。
因此,当您决定如何处理数据库连接问题时,请注意您期望每种类型的问题发生的频率。我已经看到在放弃之前尝试运行事务三次的代码like this。但是当涉及到日常查询时,这种事情很少发生,我个人只会允许异常涓涓细流到用户界面可以说“出现意外错误的地方。请再试一次。如果问题仍然存在,请联系你的管理员。“或类似的东西。