2011-12-14 106 views
3

的代码抛出异常通话过程中进行的操作是非常容易的 - 这是非常有规律的插入,然后提交更改声明,看起来:LinQ在DataContext的 - 不能给的SubmitChanges

context.tb_dayErrorLog.InsertOnSubmit(data); 
context.SubmitChanges(); 

所以真的没有什么特别的。此声明一天执行约5万次,没有任何问题,但: 约每天6 - 10次完成:

在调用SubmitChanges期间无法执行操作。

StackTrace: at System.Data.Linq.DataContext.CheckNotInSubmitChanges() 
at System.Data.Linq.Table`1.InsertOnSubmit(TEntity entity) 

我试图找出什么是可以,但无法找到线索 这种行为是非常不确定的客气话 - 它是如何能够正确地完成50K倍,几十倍呢?

DataContext首先被初始化为一个静态的,然后重新用于所有的调用,所以我想也许这就是问题所在。然后我改变了每次调用初始化,但结果非常相似。每天仍然很少例外。

有什么想法?


一些补充: 功能看起来像:

public override bool Log(ErrorLogData logData) 
    { 

     try 
     { 
      logData.ProcessID = _processID; 
      //Create new log dataset 
      var data = new DataRecord 
      { 
       application = logData.Application, 
       date = DateTime.Now, 
       Other = logData.Other, 
       process = logData.ProcessName, 
       processid = logData.ProcessID, 
       severity = logData.Severity, 
       username = logData.UserName, 
       Type = (short)logData.ErrorType 
      }; 


      var context = new DataContext(ConnectionString); 

      context.tb_dayErrorLog.InsertOnSubmit(data); 
      context.SubmitChanges(); 

     } 
     catch (Exception ex) 
     { 
      //log log in eventviewer 
      LogEvent(logData.ToString(), ex); 
      return false; 
     } 
     return true; 
    } 

这么简单的记录初始化,然后再插入。

正如我在评论中写道,同时通过Ado.Net和SqlCommand的这个问题不存在的做同样的事情...

所以我的好奇心让我想到,为什么?

+0

我想我们需要一些额外的信息。这段代码是否在计划任务上运行?这个程序的多个实例可能同时运行吗?无论如何,这只是一个猜测,只有两行代码需要分析。 –

+0

“数据”上的任何事件? –

+0

这是非常简单的函数,它只执行一个记录插入,为每个调用初始化DC,因此无论它是否并发? 有趣的是,当我用旧的ADO.Net SqlCommand执行db调用,那么问题不会发生...... 因此,在旧的Ado.Net中打开连接始终为您分配一个新的连接。 context = new DataContext(ConnectionString); 是不是做同样的事情? – Johnny

回答

4

这听起来像是一个线程问题,当另一个线程位于SubmitChanges中间时,您在一个线程上调用Log并因此调用SubmitChanges。

我怀疑你的DataContext仍然是一个全局静态变量。

试着改变你的登录方法

using (var context = new DataContext(ConnectionString)) 
{ 
    context.tb_dayErrorLog.InsertOnSubmit(data); 
    context.SubmitChanges(); 
} 
+0

对不起,在第一篇文章中的前一个函数中,我错误地键入了它,因为存在 var context = new DataContext(ConnectionString); (它没有'var'关键字 - 但它只是输入一个帖子的错误) - 所以实际上它使得你提出的一样 – Johnny

+0

好吧,也许不是相同的,因为它不是直接在通话结束后处置,但DataContext稍后由GarbageColector放弃。 但无论如何,我会尝试以这种方式处理它,因为无论如何,我都无法解决其他解决方案。 – Johnny

0

@SgMoore点并发问题,在我的情况下,它确实是。如果是这种情况,另一种方法是像这样使用锁:

String lockValue = ""; 

    lock (lockValue) 
    { 
     context.tb_dayErrorLog.InsertOnSubmit(data);//UPDATE: concurrency error can occur here too 
     context.dc.SubmitChanges(); 
    }