这里有一些插入代码
gkInfo.data.ToList()
.ForEach(p => p.hour.ToList()
.ForEach(r => r.block.ToList()
.ForEach(q =>
{
var v = new VarValues();
v.dt = DateTime.Parse(p.target_date + " " + (r.value - 1).ToString() + ":00:00");
v.id_objecttype = config.stations.Where(i => i.text == q.station_name).Single().id_objecttype;
v.id_object = q.bnum.ToString();
v.id_param = config.stations.Where(i => i.text == q.station_name).Single().id_param;
v.pl_lev = 3;
v.source = 0;
v.value = q.block_state;
v.version = version;
v.description = q.change_type;
m53500context1.VarValues.InsertOnSubmit(v);
}
)));
m53500context1.SubmitChanges();
和这段代码,锁表。 我可以避免吗?还是不可能?
答案 0 :(得分:0)
虽然我不知道有关您问题的所有细节,但这些模式似乎非常熟悉。通常,您需要在数据库中进行大的更新,但同时您仍然需要数据库可用,例如,如果有一个网站正在处理数据集,则更新时不会超时正在进行的业务。
有时,更新操作可以是来自其他数据库的常规导出,有时会计算一些缓存,与您提供的示例不同。
如果您需要更新是事务性的(即全部或全部),则锁定没有真正的方法。当更新正在进行时,表被锁定。如果您不需要交易,那么您可以尝试分解更新到较小批次。 SubmitChanges,包装单个事务中的所有更改,因此您需要使用多个SubmitChanges,因此每个单独的事务都很快,因此不能长时间锁定表。
如果要求使用事务性,则可以在暂存区域中插入,即不在其他进程读取的同一个表中。当插入完成后,你找出方法来交换区域。这可能会因为你可能没有考虑到这个表的更新而变得复杂,但我不知道你的情况是否属实。
在最坏的情况下,您需要有一些应用程序逻辑,它知道更新正在进行中,并且在发生更新时,它会从备用位置读取数据。当然,您必须提供此备用位置(副本)才能阅读。
没有硬性和快速的答案,但有一些事情(上面)你可以尝试。也可以随时告诉您有关具体任务/要求的更多信息。
答案 1 :(得分:0)
请参阅:LINQ To SQL NO_LOCK。您需要为事务设置不同的隔离级别。