2017-05-24 2 views
0

Pourriez-vous s'il vous plaît m'aider à confirmer/infirmer mes doutes en utilisant Serializable isolationlevel. Je veux m'assurer que j'ai choisi un bon IsolationLevel pour la méthode suivante AddUserTournament. Chaque fois que cette transaction est en cours d'exécution, je veux être sûr à 100%, que entity.seats est à jour - empêchant toute autre transaction d'ajouter des utilisateurs simultanément. Puis-je implémenter cela en utilisant un IsolationLevel plus lâche, ou est-ce que cela semble être la bonne façon?Transactions: IsolationLevel défini sur Serializable - est-ce correct?

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 et ADO.NET sont deux technologies très différentes, ne les marquent pas toutes les deux comme si la question faisait référence aux deux. Selon votre code, vous utilisez EntityFramework donc ADO.NET est totalement hors de propos –

+0

Aussi simplement votre logique 'if' ou faites-le en étapes ... aussi l'entité est passée, puis redéfinir ... ne fait pas de bonne programmation dans mon livre. – Seabizkit

Répondre

0

Je sais que cela ne répond pas à votre question, mais je pense que je devrais indiquer comment la rendre plus lisible. Juste pour montrer comment vous pourriez réécrire «si» en quelque chose de lisible.

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

vous verriez alors que le chèque nul n'est pas nécessaire que cette méthode ne devrait pas être en mesure d'être appelé sans personne ... Je qualifierais ce qu'ils sont les choses sauf si vous utilisez des médicaments génériques que vous aint ici .