MAX(フィールド)+1 FROMを選択…並行性の問題
-
08-07-2019 - |
質問
こんにちは昨日、パートナーアプリケーションの原因での同時実行が怖くて、特に挿入でCRUDS操作に問題がありました。そこで、SQLプロファイラーを実行し、彼のinsertステートメントはトランザクションを使用せず、彼も使用していることに注意してください:
INSERT INTO TABLEA VALUES ( (SELECT MAX(NUMBERFIELD) +1 FROM TABLEA), ....);
主キーの生成にMAX()+ 1を使用しないようにするにはどうすればよいですか?自動インクリメントまたはトランザクションスコープを使用することをお勧めしますが、彼はそれを望んでいないか、それを達成する方法を知らないかもしれませんが、これをリードする別の方法はありますか?
SQLおよびC ++ 1.1の使用
*これは私のコードではありませんが、この投稿を彼に見せることを検討するかもしれません。なぜなら、彼はすべての意見を歓迎することを考慮する必要があると思うからです。 :)
解決
正しくコーディングすれば、IDENTITYソリューションと同じ並行性を実現できるはずです。直感的ではありません。ロックすると同時実行性が低下すると考えられます。しかし、5つの異なる接続でテーブルを叩きながらいくつかのテストを実行し、MAX + 1トリックがIDENTITYとほぼ同じ性能を発揮することを証明しました。次のブログ投稿の最初のセクションで議論を見ることができます:
https:// sqlblog .org / 2009/10/12 / bad-habits-to-kick-making-assumes-about-identity
とにかく私がお勧めする構文です(INSERT ... VALUES(SUBQUERY)モデルを本当に信用していません、申し訳ありません):
DECLARE @NextID INT;
BEGIN TRANSACTION;
SELECT @NextID = COALESCE(MAX(NumberColumn), 0) + 1
FROM dbo.TableA WITH (UPDLOCK);
INSERT dbo.TableA SELECT @NextID;
COMMIT TRANSACTION;
エラー処理の部分(簡潔にするため省略)を想像する必要がありますが、ドリフトが発生すると思います。
もちろん、これを福音のために取ってはいけません。データとアクセスパターンを使用してハードウェアでテストを実行し、この方法によって同時実行性が損なわれるかどうかを判断する必要があります。これは、「依存する」ものの1つになります。回答。
他のヒント
主キー列を IDENTITY
にすることを検討しましたか? SQL Serverが列の値を自動的に生成します。
CREATE TABLE Test (
Id int identity primary key not null
-- ...
)