2017-05-24 3 views
0

Könnten Sie mir bitte helfen, meine Zweifel mit dem Serializable Isolationsgrad zu bestätigen/zu entkräften?Transaktionen: IsolationLevel auf Serializable gesetzt - ist das korrekt?

Ich möchte sicherstellen, dass ich eine richtige IsolationLevel für die folgende Methode AddUserTournament gewählt habe. Wann immer diese Transaktion ausgeführt wird, möchte ich 100% sicher sein, dass entity.seats auf dem neuesten Stand ist - verhindert, dass andere Transaktionen Benutzer gleichzeitig hinzufügen.

Kann ich dies mit einem losen IsolationLevel implementieren, oder scheint dies der richtige Weg?

public void AddUserTournament(Tournament entity, User user) 
    { 
     try 
     { 
      // Add the user to tournament. Do this with a snapshot-isolationlevel 
      using (var transaction = _dbContext.Database.BeginTransaction(System.Data.IsolationLevel.Serializable)) 
      { 
       try 
       { 
        // Get all users and include their relations to tournament 
        entity = 
         _dbContext.Tournaments.Where(e => e.TournamentId == entity.TournamentId) 
          .Include(t => t.Users) 
          .FirstOrDefault(); 

        // Get the user 
        user = _dbContext.Users.SingleOrDefault(e => e.UserId == user.UserId); 

        // Check if there are available seats in the tournament and if user exist amoung enrolled users 
        if (entity != null && entity.Seats > entity.Users.Count && 
         entity.Users.All(e => user != null && e.UserId != user.UserId)) 
        { 

         // Add user 
         entity?.Users.Add(user); 

         // Save changes 
         _dbContext.SaveChanges(); 

         // Commit transaction 
         transaction.Commit(); 

        } 
       } 
       catch (Exception) 
       { 
        transaction.Rollback(); 
       } 
      } 
     } 
     catch (DbEntityValidationException ex) 
     { 
      throw new FaultException(new FormattedDbEntityValidationException(ex).Message); 
     } 
    } 
+1

EntityFramework und ADO.NET sind zwei sehr unterschiedliche Technologien, markieren Sie sie nicht beide, als ob sich die Frage auf beide bezieht. Wie in Ihrem Code verwenden Sie EntityFramework, so ADO.NET ist völlig irrelevant –

+0

Auch einfach Ihre "if" Logik oder tun Sie es in Schritten ... auch Entität wird übergeben und dann überschreiben ... nicht für eine gute Programmierung in meinem Buch. – Seabizkit

Antwort

0

Ich weiß, dass dies Ihre Frage nicht beantwortet, aber ich fühle, dass ich darauf hinweisen sollte, wie man es lesbarer macht.

Nur zeigen, wie Sie Sie "wenn" in etwas lesbar umschreiben könnten.

//after you refactor it more you will see that this check is actually not needed. 
if (entity != null) 
{ 
    //Called entity but represents a Tournament 
    //so the check is to see if the T has more seats than the current attending users 
    if(entity.Seats.Count > entity.Users.Count) 
    { 
     //this was to check if the user is already in the attending users 
     //if(entity.Users.All(e => user != null && e.UserId != user.UserId)) 

     var userInSeats = entity.Users.Where(x=>x.UserId == user.UserId).SingleOrDefualt(); 
     if(userInSeats == null) 
     { 
      // Add user 
      entity.Users.Add(user); 

      // Save changes 
      _dbContext.SaveChanges(); 

      // Commit transaction 
      transaction.Commit(); 
     } 
    } 
} 

Sie würden dann sehen, dass die Nullprüfung nicht, da diese Methode benötigt wird, sollte ohne Einheit nicht in der Lage sein, genannt zu werden ... Ich würde die Dinge nennen, was sie sind, wenn Sie Generika verwenden, die Sie hier aint .

Verwandte Themen