2017-05-12 5 views
-2

Nous utilisons une isolation de session sérialisable dans notre application. Le comportement prévu est le suivant: lorsqu'un utilisateur insère une nouvelle ligne, il doit vérifier la présence de la ligne avec la même clé et la mettre à jour si la ligne est trouvée. Mais j'ai trouvé plusieurs lignes créées pour la même clé dans le serveur SQL. Est-ce un problème d'isolement ou de la façon dont nous traitons l'affaire?Niveau d'isolement SQL

Voici le code que je utilise,

private int getNextNumber(String objectName, Connection sqlConnection) throws SQLException { 
    // TODO Auto-generated method stub 
    int number = 0; 

    try{ 

     sqlConnection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); 

     System.out.println("##### Transaction isolation set : " + sqlConnection.getTransactionIsolation()); 

     Statement stmt = sqlConnection.createStatement(); 
     ResultSet rs = stmt.executeQuery("select * from [dbo].[db] where DocumentNumber = '" + objectName.toString() + "' FOR UPDATE"); 

     while(rs.next()) { 
      printNumber = rs.getInt("PrintNumber"); 
     } 


     System.out.println("#### Print number found from sql is : " + printNumber); 

     if(printNumber == 0) { 
      printNumber = printNumber + 1; 
      stmt.execute("INSERT INTO [dbo].[db] (number, DocumentNumber) VALUES (1 ,'" + objectName.toString() + "')"); 
     } else { 
      number = number + 1; 
      stmt.execute("UPDATE [dbo].[db] SET Number =" + number + " WHERE DocumentNumber ='" + objectName.toString() + "'"); 
     } 

     //sqlConnection.commit(); 
    }catch(Exception e) { 
     sqlConnection.rollback(); 
     e.printStackTrace(); 
    } finally { 
     sqlConnection.commit(); 
    } 
    return number; 
} 

Merci, Kishor Koli

+0

-> "la façon dont nous gérons le boîtier" –

+2

Pouvez-vous poster le code traitant le "cas"? Utilisez-vous une instruction de fusion? Utilisez-vous les anciennes EXISTS vérifier avec une transaction explicite correctement emballé autour du bloc entier? Besoin de plus d'informations –

+0

@PhilSchwartz J'ai mis à jour la question avec du code. –

Répondre

1

Il est un problème avec la façon dont votre base de données est mis en place. Vous avez besoin d'une contrainte unique pour imposer l'unicité. Vous pouvez vérifier au moment de l'insertion tout ce que vous voulez, mais une contrainte unique est la seule façon de travailler à 100%, c'est donc une perte de temps à sélectionner avant de l'insérer dans l'espoir d'éviter un doublon. Insérer, attraper l'exception/erreur ou continuer.