2011-12-14 4 views
3

Кода, который метательное исключения чрезвычайно просто - это очень регулярная вставка, а затем представить изменения заявления, которое выглядит:LinQ DataContext - Операция не может быть выполнена во время вызова SubmitChanges

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

Так на самом деле ничего особенного , Это заявление выполняется около 50 тысяч раз в день без каких-либо проблем, но: около 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

Я думаю, нам нужна дополнительная информация. Выполняется ли этот код, скажем, по запланированной задаче? Возможно ли одновременное выполнение нескольких экземпляров этой программы? В любом случае, это всего лишь предположение, и только 2 строки кода для анализа. –

+0

Любые события на ваших 'данных'? –

+0

Это очень простая функция, которая делает только одну запись, инициализируя DC для каждого вызова, так что независимо от того, что это одновременно или нет? Самое смешное, что когда я выполняю вызов db со старым хорошим ADO.Net SqlCommand, тогда проблема не возникает ... Таким образом, открытие соединения в старой Ado.Net всегда присваивает вам новое соединение. context = new DataContext (ConnectionString); не делает такой же предмет? – Johnny

ответ

4

Это звучит как проблема с потоками, в которой вы вызываете Log и, следовательно, SubmitChanges в одном потоке, когда другой поток находится в середине 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(); 
    } 

 Смежные вопросы

  • Нет связанных вопросов^_^