2017-05-12 15 views
-2

私たちはアプリケーションでシリアル化可能なセッション分離を使用しています。意図した動作は、ユーザーが新しい行を挿入しようとしたときに、同じキーを持つ行が存在するかどうかをチェックし、同じ行が見つかった場合は更新する必要があります。しかし、私はSQLサーバー内の同じキーのために作成された複数の行が見つかりました。この問題は孤立しているのか、それとも私たちがその事件を処理しているのか?SQL分離レベル

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

おかげで、 Kishorコリ

+0

- >「ケースを処理する方法」 –

+2

「ケース」を扱うコードを掲載することはできますか?マージステートメントを使用していますか?古いファッションEXISTSチェックを使用して、ブロック全体で適切にラップされた明示的なトランザクションをチェックしていますか?詳細が必要です。 –

+0

@PhilSchwartz私はコードで質問を更新しました。 –

答えて

1

は、それはあなたのデータベースが設定されている方法に問題だ、私が使用していたコードです。一意性を強制するためには一意制約が必要です。挿入時に好きなだけチェックすることができますが、ユニークな制約が100%機能する唯一の方法ですので、重複を避けることを希望して挿入する前に時間を選択するだけです。挿入するか、例外/エラーをキャッチするか、続行してください。

関連する問題