我写了一个插入方法,它使用linq并循环遍历2个列表,第一个能够达到14k个对象并发送大约8k个对象。
每当我运行此方法时,我总是得到“Transaction Timeout Exception”。你能帮我改进一下吗?
public void InsertNewInventoryGoodsEvents(List<GoodsEvent> eventsList, List<InventoryGoods> goodsList)
{
InventoryGoodsEvents ige = new InventoryGoodsEvents();
TransactionScope scope= new TransactionScope();
int i = 0;
const int batchSize = 50; // or even 50
foreach (InventoryGoods good in goodsList)
{
if (i == 50)
{
if (scope != null)
{
context.SubmitChanges();
}
i = 0;
}
try
{
foreach (GoodsEvent g in eventsList)
{
if (g.Gid == good.Gid)
{
ige = new InventoryGoodsEvents() { EventId = g.Id, InventoryGood = good.Id };
context.InventoryGoodsEvents.InsertOnSubmit(ige);
}
}
}
catch (Exception ex)
{
ex.ToString();
}
++i;
}
if (scope != null)
{
context.SubmitChanges();
scope.Complete();
}
}
答案 0 :(得分:0)
在同一个交易中完成所有插入是否很重要?如果没有,您是否可以为要插入的每批商品使用新的交易?这应该可以防止交易开放时间过长和超时。
答案 1 :(得分:0)
var itsReallyJustAJoin = (from g in GoodEvent
join i in InventoryEvent on g.Gid equals i.Gid
select new {g.Id, good.Id}).ToList();
然后你可以插入这些你想要的。看起来你现在正在做50批次?如果你愿意的话,你可以继续...这将占用交易范围之外的所有工作,所以如果你的结果不是太大,你可以立刻在那里完成所有工作。
答案 2 :(得分:0)
我在仔细考虑之后重新编写了这个方法,结果如下:
public void InsertNewInventoryGoodsEvents(List<GoodsEvent> eventsList, List<InventoryGoods> goodsList)
{
List<InventoryGoodsEvents> mylist = new List<InventoryGoodsEvents>();
InventoryGoodsEvents ige = new InventoryGoodsEvents();
foreach (GoodsEvent g in eventsList)
{
foreach (InventoryGoods ig in goodsList)
{
if (ig.Gid == g.Gid)
{
ige = new InventoryGoodsEvents();
ige.EventId = g.Id;
ige.InventoryGood = ig.Id;
mylist.Add(ige);
}
}
}
using (var scope = new TransactionScope())
{
foreach (InventoryGoodsEvents ip in mylist)
{
context.InventoryGoodsEvents.InsertOnSubmit(ip);
}
context.SubmitChanges();
scope.Complete();
}
}
我喜欢MikeM关于简化事情的想法,但我们会看到我会保留哪种方法。