2011-12-14 8 views
3

の呼び出し中に実行することはできません。きゅうのDataContext - これは非常に定期的に挿入され、その後に見えた変化書を提出 - 操作が例外を投げているコードは非常に簡単ですでSubmitChanges

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

をだから、本当に何も特別な。このステートメントは問題なく一日に約50,000回実行されますが、 と終了日約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オブジェクトこの問題occuringされていないことで、同じことをしながら

私は、コメントに書いたように?

+0

私はいくつかの追加情報が必要と思います。このコードは、スケジュールされたタスクで実行されていますか?このプログラムの複数のインスタンスが同時に実行される可能性はありますか?とにかく、解析するコードは2行のみで、それはちょっと推測です。 –

+0

あなたの 'data'のイベントはありますか? –

+0

これは、すべての呼び出しに対してDCを初期化するという、単なるレコード挿入を行う非常に単純な関数なので、同時かどうかは関係ありません。 古いADO.Net SqlCommandを使用してdbコールを実行すると問題が発生しないというのは面白いことです... 古いAdo.Netの接続を開くと、常に新しいconnが割り当てられます。 コンテキスト=新しいDataContext(ConnectionString); は同じことをしていませんか? – Johnny

答えて

4

これは、別のスレッドがSubmitChangesの途中にあるときにLogを呼び出して1つのスレッドでSubmitChangesを呼び出しているスレッドの問題のようです。

あなたのDataContextがまだグローバルな静的変数であると思われます。

は、同時実行の問題に、それは本当にだった私の場合は

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

申し訳ありませんが、最初の投稿の前の関数では、それが間違って入力しました var context = new DataContext(ConnectionString); (これは 'var'キーワードなしでしたが、投稿を入力するだけで間違いでした) - 実際には、あなたが提案しているものと同じになります – Johnny

+0

ok、多分同じではない、通話の終了直後に処分しないとにかくDataContextは後でGarbageColectorによって処理されます。 しかし、とにかく私はこの方法で処分しようとします。なぜなら、とにかく他の解決策から外れているからです... – Johnny

0

@SgMooreの点にごLogメソッドを変更してみてください。そのような場合は、別の方法として、次のようにロックを使用することです:

String lockValue = ""; 

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