(他の種類の番号の中でも)インシデント番号を使用するアプリケーションがあります。これらの番号は、カウンターの現在の値を含む「Number_Setup」と呼ばれるテーブルに格納されます。
アプリが新しいインシデントを生成すると、number_setupテーブルが作成され、必要な番号カウンター行が取得されます(カウンターは毎日、毎週などにリセットでき、intとして保存されます)。次に、カウンターをインクリメントし、新しい値で行を更新します。
アプリケーションはマルチユーザーです(一度に約100人のユーザー、および数百のインシデントレコードを実行して取得し、それぞれのインシデント番号を要求するSQLジョブ)。インシデントテーブルには、重複してはならない重複するインシデント番号がいくつかあります。
ストアドプロシージャは、次のカウンタを取得するために使用されます。
SELECT @Counter = counter、@ ShareId = share_id、@ Id = id FROM Number_Setup WHERE LinkTo_ID = @ LinkToId AND Counter_Type ='I' IF isnull(@ ShareId、0)> 0 始める -親カウンターを使用します SELECT @Counter = counter、@ ID = id FROM Number_Setup WHERE Id = @ ShareID 終わり SELECT @NewCounter = @Counter + 1 UPDATE Number_Setup SET Counter = @NewCounter WHERE id = @ Id
そのブロックをトランザクションで囲みましたが、まだ共有ロックがあると思うので、問題が100%修正されるかどうかは完全にはわかりません。そのため、とにかくカウンターを読み取ることができます。
おそらく、updateステートメントでカウンターが更新されていないことを確認できます
UPDATE Number_Setup SET Counter = @NewCounter WHERE Counter = @Counter @@ ERROR=0かつ@@ROWCOUNT>0の場合 トランザクションのコミット そうしないと ロールバックトランザクション
これは、金融アプリなどの請求書番号でよくある問題だと確信しています。
ロジックをコードに入れて、そのレベルでロックを使用することもできません。私もHOLDLOCKでロックしましたが、そのアプリケーションがわかりません。2つのSELECTステートメントに配置する必要がありますか?
重複が作成されないようにするにはどうすればよいですか?