2016-07-11 13 views
0

これは私が直面している典型的な問題です。 各レコードに増分順次キーがある非同期TPLを使用して、データベースに2k行を挿入したいとします。非同期データベース挿入操作のシーケンシャルID生成

ここ

は以下のものです::サービス側の

まず私は、データベースから最大SEQキーを取得

は、私は私のサービスSideの3層を有します。

Data.Upload.UploadDetails gd = new Data.Upload.UploadDetails(); 

try 
{ 

    var Max_seq_key = gd.getGroupMembershipSeqKeyDetails(); 

このgetGroupMembershipSeqKeyDetails方法は次のようになりDAL層である:

public long getGroupMembershipSeqKeyDetails() 
    { 
     Repository rep = new Repository(); 
     string strSPQuery = string.Empty; 
     List<long> listSeqKey = new List<long>(); 
     long strMaxSeqKey = -1; 

     try 
     { 
      listSeqKey = rep.ExecuteSqlQuery<Int64>(SQL.Upload.UploadDetails.getMaxSeqKeySQL()).ToList(); 
      strMaxSeqKey = listSeqKey[0] != null ? listSeqKey[0] : strMaxSeqKey; 
      return strMaxSeqKey; 
     } 
     catch (Exception e) 
     { 
      return strMaxSeqKey; 
     } 
    } 

だから、サービス層では、私は、データベースから最大配列のキーを取得します。

ここでは、サービス側のの次の文を使用して2kレコードを挿入します。

  foreach (var grpMem in input.ListGroupMembershipUploadDetailsInput.GroupMembershipUploadInputList) 
      { 
       try 
       { 
        Task.Run(() => gd.insertGroupMembershipUploadDetails(grpMem, 
                input.ListChapterUploadFileDetailsInput, ++Max_seq_key, ++Max_grp_seq_key, Lst_com_unit_key, trans_key)); 
       } 

しかし、この++ Max_seq_keyは必ずしも保証されません。

時々私は、データベース内のような結果を得る:

enter image description here

は、どのように私はこの増分SEQキーは常に別のスレッドで実行されているのは勿論である以前挿入されたレコードよりも1以上であることを確認することができますか?

+0

デニスの答えが述べているように、DBに各番号を生成させることをお勧めします。しかし、 '++'については、これはスレッドセーフな操作であることは誤解されていますが、それはアトミックではないため、スレッドセーフではありません。スレッドセーフインクリメントの場合、 'Interlocked.Increment'を使用できます。 –

+0

' getMaxSeqKeySQL'にはバグがあります。コードがないので、それが何であるかは言えません。 – usr

答えて

3

どのように私はこの増分SEQキーが明白な答えは、「クライアント側で鍵を生成しない」は常に1

以上であることを確認することができます。
ちょうど約max + 1忘れて。

データベース機能を使用して、identityカラムまたはsequencesなどの一意のキーを生成します。

リンクはMS SQL固有ですが、別のRDBMSの同じドキュメントを簡単に見つけることができます。ここにOracleの1つです。

P.S.あなたの "非同期"コードは本当に非同期ではありません - リポジトリは非同期の方法で書き直さなければなりません。

関連する問題