11

SQLServerの分離レベルを完全に理解しようとしています-特にREPEATABLEREAD。

トランザクションを開始し、いくつかのデータの周りにカーソルを置くsprocがあります(ブーヒス)。これはかなりの量のデータになる可能性があるため、実行に時間がかかる場合があります。

その後、COMMITまたはROLLBACKします。

この間、トランザクションが閉じられる前に、影響を受ける行の一部をREADにするメソッドを誰かが呼び出すと、最初のメソッドが完了するまでこのメソッドが停止することを理解しています。その後、データが提供されます(最初にタイムアウトが発生しない限り)

私は正しいと思いますが、質問は-私ですか?!

4

2 に答える 2

24

REPEATABLE READSELECTsトランザクションが終了するまで、配置した共有ロックを解除できないようにします。

transaction 1asREAD COMMITTEDを使用すると、 transaction で選択した行を transaction で更新できます。21

transaction 1asREPEATABLE READを使用すると、 transaction で行を選択した後で、その行を transaction で更新することはできません21

シナリオ:

コミットされた読み取り

1 SELECT -- places a shared lock and immediately lifts it.
2 UPDATE -- places an exclusive lock. Succeeds.
1 SELECT -- tries to place a shared lock but it conflicts with the exclusive lock placed by 2. Locks.

反復可能な読み取り

1 SELECT -- places a shared lock and keeps it
2 UPDATE -- tries to places an exclusive lock but it's not compatible with the shared lock. Locks
1 SELECT -- the lock is already placed. Succeeds.

アップデート:

あなたの質問についてはSQL Server、 では、を使用SELECTsしても互いにロックしません。REPEATABLE READそれらが配置する共有ロックは互いに互換性があるためです。

CREATE TABLE t_lock (id INT NOT NULL PRIMARY KEY, value INT NOT NULL)
INSERT
INTO    t_lock
VALUES (1, 1)

-- Session 1

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 2

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRANSACTION
DECLARE @id INT
DECLARE cr_lock CURSOR DYNAMIC
FOR
SELECT  id
FROM    t_lock
OPEN    cr_lock
FETCH   cr_lock

id
--
1

-- Session 1

DEALLOCATE cr_lock
COMMIT

-- Session 2

DEALLOCATE cr_lock
COMMIT
于 2010-01-14T16:31:40.830 に答える
2

正しい。

MSDNからの完全な説明:

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

共有ロックは、トランザクション内の各ステートメントによって読み取られるすべてのデータに配置され、トランザクションが完了するまで保持されます。これにより、現在のトランザクションによって読み取られた行が他のトランザクションによって変更されるのを防ぐことができます。他のトランザクションは、現在のトランザクションによって発行されたステートメントの検索条件に一致する新しい行を挿入できます。その後、現在のトランザクションがステートメントを再試行すると、新しい行が取得され、ファントム読み取りが発生します。共有ロックは、各ステートメントの最後に解放されるのではなく、トランザクションの最後まで保持されるため、同時実行性はデフォルトの READ COMMITTED 分離レベルよりも低くなります。このオプションは、必要な場合にのみ使用してください。

于 2010-01-14T16:29:40.447 に答える