2016-07-11 10 views
0

Es ist ein typisches Problem, vor dem ich stehe. Ich möchte 2k Zeilen in Datenbank mit asynchronen TPL einfügen, wobei jeder Datensatz einen inkrementellen sequenziellen Schlüssel hat.Sequenzielle ID-Generierung für asynchrone Datenbankeinfügevorgänge

Ich habe 3 Schichten in meiner Service-Seite:

Hier ist, was folgt:

In Service Side:

Zuerst bekomme ich die max seq Schlüssel aus der Datenbank.

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

try 
{ 

    var Max_seq_key = gd.getGroupMembershipSeqKeyDetails(); 

Diese getGroupMembershipSeqKeyDetails Methode ist in DAL Schicht, die wie geht:

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; 
     } 
    } 

So in Service-Layer erhalte ich die max seq Schlüssel aus der Datenbank.

Jetzt möchte ich 2k Datensätze mit unter Anweisung von Service-Seite einfügen.

  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)); 
       } 

Aber diese ++ Max_seq_key nicht immer gewährleistet ist.

Manchmal erhalte ich Ergebnisse wie in der Datenbank:

enter image description here

Wie kann ich sicherstellen, dass dieser inkrementale seq Schlüssel ist immer größer als 1 ist als der vorherige Datensatz eingefügt, was natürlich auf einem anderen Thread ausgeführt wird?

+0

Wie Dennis 'Antwort sagt, ist es am besten, wenn die DB jede Zahl generiert. Aber für '++': Es ist ein bekanntes Missverständnis, dass dies eine Thread-sichere Operation ist, aber es ist nicht atomar und daher nicht Thread-sicher. Zum threadsicheren Inkrementieren können Sie 'Interlocked.Increment' verwenden –

+0

' getMaxSeqKeySQL' hat einen Fehler. Kann nicht sagen, was es ist, weil der Code fehlt. – usr

Antwort

3

Wie kann ich sicherstellen, dass dieser inkrementale seq Schlüssel ist immer größer als 1

Die offensichtliche Antwort ist „keine Tasten auf Client-Seite generieren“.
Vergessen Sie einfach max + 1 Ansatz.

Verwenden Sie Datenbankfunktionen, um eindeutige Schlüssel wie identity Spalten oder sequences zu generieren.

Links sind MS SQL-spezifisch, aber Sie können leicht die gleiche Dokumentation für ein anderes RDBMS finden, z. Hier ist eine für Oracle.

P.S. Ihr "async" -Code ist nicht wirklich asynchron - das Repository muss asynchron umgeschrieben werden.

Verwandte Themen