値受信、次のSQLを考えてみましょう:ドゥ挿入されたレコードは、必ず連続アイデンティティが
CREATE TABLE Foo
(
ID int IDENTITY(1,1),
Data nvarchar(max)
)
INSERT INTO Foo (Data)
SELECT TOP 1000 Data
FROM SomeOtherTable
WHERE SomeColumn = @SomeParameter
DECLARE @LastID int
SET @LastID = SCOPE_IDENTITY()
私は私が連続したID値を持つテーブルのFooに挿入1000行に依存することができますかどうかを知りたいです。言い換えれば、このSQLブロックが@LastID 2000を生成する場合、私が挿入した最初のレコードのIDが1001であることを確かに知ることができますか?私は主にレコードをテーブルFooに同時に挿入する複数のステートメントについて興味があります。
私はinsert文の周りに直列化可能なトランザクションを追加して、必要な振る舞いを確実にすることができますが、本当に必要ですか?シリアライズ可能なトランザクションを導入するとパフォーマンスが低下することが懸念されますが、このステートメントが実行されている間にSQL Serverが他のステートメントをテーブルFooに挿入することを許可しないと、心配する必要はありません。
非常に興味深い発見!私はあなたにこのテストをまとめることに感謝します。私はさらに、 "1000レコードを挿入"ステートメントをシリアライズ可能なトランザクションでラップしようとしましたが、無駄に、私はまだインタリーブされたレコードを取得します。しかし、 "Insert 1000 records"を直列化可能トランザクションに入れ、挿入前にトランザクション内でSELECT MAX(ID)FROM Fooを呼び出すと、レコードが連続することが保証されます。このソリューションは同時インサートを防ぎますが、パフォーマンスの低下を招くことはありません。 –
@John - ヒープ上のシリアライザブルは排他的なテーブルロックを取得するので、簡単なロックヒントで同じ効果を得ることができます。 'WITH(TABLOCKX)'これは並行性にも影響すると言っています。 –
私の間違いは、私が実行していたテストでは、テーブルFooのIDカラムにPKを追加しました。 –