0

これらのテーブルを検討します。

CREATE TABLE Status (current_partition INT) -- has a single row
CREATE TABLE RecordedValues (partition INT, value INT)

RecordedValuesを使用してテーブルに頻繁に挿入する複数のクライアントがあるとしますcurrent_partition。例:

DECLARE @current_partition INT
SET @current_partition = (SELECT TOP 1 current_partition FROM Status)
INSERT RecordedValues VALUES (@current_partition, 132)

同時に、を(定期的に)変更current_partitionし、古いパーティション値ですべての値を読み取るクライアントがあります。例:

DECLARE @old_partition INT
SET @old_partition = (UPDATE Status 
    SET current_partition += 1 
    OUTPUT deleted.*)
--
SELECT * FROM RecordedValues WHERE partition = @old_partition

後者のクライアントが実際に古いパーティション値を持つすべての行を選択するようにするにはどうすればよいですか?つまり、 SELECTが戻ったにINSERTがコミットされないようにする必要があります。

4

1 に答える 1

2

コマンドをトランザクションで実行し、分離レベルを REPEATABLE READ に設定します。

BEGIN TRANSACTION

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

DECLARE @old_partition INT
SET @old_partition = (UPDATE Status 
    SET current_partition += 1 
    OUTPUT deleted.*)
--
SELECT * FROM RecordedValues WHERE partition = @old_partition

COMMIT TRANSACTION

これにより、トランザクション内のステートメント間の一貫性が確保されます。

ドキュメントを引用するには:

「他のトランザクションによって変更されたがまだコミットされていないデータをステートメントが読み取れないこと、および現在のトランザクションが完了するまで、他のトランザクションが現在のトランザクションによって読み取られたデータを変更できないことを指定します。」

于 2012-09-09T15:28:34.857 に答える