QA@IT
«回答へ戻る

5619
 
 ---
 
-SQL Server version: SQL Server 2008 standard
+version: SQL Server 2008 Standard
+       : SQL Server 2008 付属の SQL Server Management Studio
 
 DB設定 (データベース名 `readcommited_snapshot_db`)
 ```sql

どういう問題を解決しようとしているのかわかりませんが、
何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。

例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、
※ 環境は最後に。

-- use readcommited_snapshot_db
-- TRAN A

begin
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 10 where id = 1
  waitfor delay '00:00:10' --ウェイト
commit

end
-- use readcommited_snapshot_db
-- TRAN B

begin 
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 1 where id = 1
commit

end

ウェイト中に開始された TRAN Bは、select文は成功し、update文が競合エラーとなります。

メッセージ 3960、レベル 16、状態 2、行 9
更新の競合により、スナップショット分離トランザクションが中断しました。スナップショット分離を使用してデータベース 'readcommited_snapshot_db' のテーブル 'dbo.sample1' に直接または間接的にアクセスし、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。

なお、update文を削除すれば成功しますが selectではTRAN Aでの更新前の値が取得されます。

SQL Serverでは デフォルトの状態のデータベースは READ_COMMITEDトランザクションなので、
スナップショットを有効にしていない場合で、SET TRANSACTION ISOLATION LEVEL~を消したSQLを試せば
TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。

ところで、SQL Serverで Select ~ For Updateって トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( WITH(UPDLOCK) を代わりに使うような気が )、今は違うんでしょうか?


version: SQL Server 2008 Standard
: SQL Server 2008 付属の SQL Server Management Studio

DB設定 (データベース名 readcommited_snapshot_db)

ALTER DATABASE readcommited_snapshot_db
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE readcommited_snapshot_db
SET READ_COMMITTED_SNAPSHOT ON

テーブル sample1

CREATE TABLE sample1(
    id int primary key,
    f1 int,
    f2 int,
);
どういう問題を解決しようとしているのかわかりませんが、
何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。

例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、
※ 環境は最後に。

```sql
-- use readcommited_snapshot_db
-- TRAN A

begin
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 10 where id = 1
  waitfor delay '00:00:10' --ウェイト
commit

end
```

```sql
-- use readcommited_snapshot_db
-- TRAN B

begin 
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 1 where id = 1
commit

end
```

ウェイト中に開始された TRAN Bは、select文は成功し、update文が競合エラーとなります。
```
メッセージ 3960、レベル 16、状態 2、行 9
更新の競合により、スナップショット分離トランザクションが中断しました。スナップショット分離を使用してデータベース 'readcommited_snapshot_db' のテーブル 'dbo.sample1' に直接または間接的にアクセスし、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。
```

なお、update文を削除すれば成功しますが selectではTRAN Aでの更新前の値が取得されます。

SQL Serverでは デフォルトの状態のデータベースは READ_COMMITEDトランザクションなので、
スナップショットを有効にしていない場合で、`SET TRANSACTION ISOLATION LEVEL~`を消したSQLを試せば
TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。

ところで、SQL Serverで `Select ~ For Update`って トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( `WITH(UPDLOCK)` を代わりに使うような気が )、今は違うんでしょうか?

---

version: SQL Server 2008 Standard
       : SQL Server 2008 付属の SQL Server Management Studio

DB設定 (データベース名 `readcommited_snapshot_db`)
```sql
ALTER DATABASE readcommited_snapshot_db
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE readcommited_snapshot_db
SET READ_COMMITTED_SNAPSHOT ON
```

テーブル sample1
```sql
CREATE TABLE sample1(
    id int primary key,
    f1 int,
    f2 int,
);
```

環境情報の追加

5619
 何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。
 
 例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、
+※ 環境は最後に。
+
 ```sql
-use readcommited_snapshot_db
+-- use readcommited_snapshot_db
 -- TRAN A
 
 begin
 ```
 
 ```sql
-use readcommited_snapshot_db
+-- use readcommited_snapshot_db
 -- TRAN B
 
 begin 
 TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。
 
 ところで、SQL Serverで `Select ~ For Update`って トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( `WITH(UPDLOCK)` を代わりに使うような気が )、今は違うんでしょうか?
+
+---
+
+SQL Server version: SQL Server 2008 standard
+
+DB設定 (データベース名 `readcommited_snapshot_db`)
+```sql
+ALTER DATABASE readcommited_snapshot_db
+SET ALLOW_SNAPSHOT_ISOLATION ON
+
+ALTER DATABASE readcommited_snapshot_db
+SET READ_COMMITTED_SNAPSHOT ON
+```
+
+テーブル sample1
+```sql
+CREATE TABLE sample1(
+    id int primary key,
+    f1 int,
+    f2 int,
+);
+```

どういう問題を解決しようとしているのかわかりませんが、
何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。

例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、
※ 環境は最後に。

-- use readcommited_snapshot_db
-- TRAN A

begin
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 10 where id = 1
  waitfor delay '00:00:10' --ウェイト
commit

end
-- use readcommited_snapshot_db
-- TRAN B

begin 
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 1 where id = 1
commit

end

ウェイト中に開始された TRAN Bは、select文は成功し、update文が競合エラーとなります。

メッセージ 3960、レベル 16、状態 2、行 9
更新の競合により、スナップショット分離トランザクションが中断しました。スナップショット分離を使用してデータベース 'readcommited_snapshot_db' のテーブル 'dbo.sample1' に直接または間接的にアクセスし、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。

なお、update文を削除すれば成功しますが selectではTRAN Aでの更新前の値が取得されます。

SQL Serverでは デフォルトの状態のデータベースは READ_COMMITEDトランザクションなので、
スナップショットを有効にしていない場合で、SET TRANSACTION ISOLATION LEVEL~を消したSQLを試せば
TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。

ところで、SQL Serverで Select ~ For Updateって トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( WITH(UPDLOCK) を代わりに使うような気が )、今は違うんでしょうか?


SQL Server version: SQL Server 2008 standard

DB設定 (データベース名 readcommited_snapshot_db)

ALTER DATABASE readcommited_snapshot_db
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE readcommited_snapshot_db
SET READ_COMMITTED_SNAPSHOT ON

テーブル sample1

CREATE TABLE sample1(
    id int primary key,
    f1 int,
    f2 int,
);
どういう問題を解決しようとしているのかわかりませんが、
何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。

例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、
※ 環境は最後に。

```sql
-- use readcommited_snapshot_db
-- TRAN A

begin
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 10 where id = 1
  waitfor delay '00:00:10' --ウェイト
commit

end
```

```sql
-- use readcommited_snapshot_db
-- TRAN B

begin 
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 1 where id = 1
commit

end
```

ウェイト中に開始された TRAN Bは、select文は成功し、update文が競合エラーとなります。
```
メッセージ 3960、レベル 16、状態 2、行 9
更新の競合により、スナップショット分離トランザクションが中断しました。スナップショット分離を使用してデータベース 'readcommited_snapshot_db' のテーブル 'dbo.sample1' に直接または間接的にアクセスし、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。
```

なお、update文を削除すれば成功しますが selectではTRAN Aでの更新前の値が取得されます。

SQL Serverでは デフォルトの状態のデータベースは READ_COMMITEDトランザクションなので、
スナップショットを有効にしていない場合で、`SET TRANSACTION ISOLATION LEVEL~`を消したSQLを試せば
TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。

ところで、SQL Serverで `Select ~ For Update`って トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( `WITH(UPDLOCK)` を代わりに使うような気が )、今は違うんでしょうか?

---

SQL Server version: SQL Server 2008 standard

DB設定 (データベース名 `readcommited_snapshot_db`)
```sql
ALTER DATABASE readcommited_snapshot_db
SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE readcommited_snapshot_db
SET READ_COMMITTED_SNAPSHOT ON
```

テーブル sample1
```sql
CREATE TABLE sample1(
    id int primary key,
    f1 int,
    f2 int,
);
```

回答を投稿

どういう問題を解決しようとしているのかわかりませんが、
何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。

例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、

use readcommited_snapshot_db
-- TRAN A

begin
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 10 where id = 1
  waitfor delay '00:00:10' --ウェイト
commit

end
use readcommited_snapshot_db
-- TRAN B

begin 
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 1 where id = 1
commit

end

ウェイト中に開始された TRAN Bは、select文は成功し、update文が競合エラーとなります。

メッセージ 3960、レベル 16、状態 2、行 9
更新の競合により、スナップショット分離トランザクションが中断しました。スナップショット分離を使用してデータベース 'readcommited_snapshot_db' のテーブル 'dbo.sample1' に直接または間接的にアクセスし、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。

なお、update文を削除すれば成功しますが selectではTRAN Aでの更新前の値が取得されます。

SQL Serverでは デフォルトの状態のデータベースは READ_COMMITEDトランザクションなので、
スナップショットを有効にしていない場合で、SET TRANSACTION ISOLATION LEVEL~を消したSQLを試せば
TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。

ところで、SQL Serverで Select ~ For Updateって トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( WITH(UPDLOCK) を代わりに使うような気が )、今は違うんでしょうか?

どういう問題を解決しようとしているのかわかりませんが、
何の前提も無く比較した場合共有ロックとスナップショット分離は別の物です。

例えばスナップショット分離の 2つのトランザクション TRAN A と TRAN Bで、
```sql
use readcommited_snapshot_db
-- TRAN A

begin
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 10 where id = 1
  waitfor delay '00:00:10' --ウェイト
commit

end
```

```sql
use readcommited_snapshot_db
-- TRAN B

begin 
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

begin tran
  select * from sample1;
  update sample1 set f1 = f1 + 1 where id = 1
commit

end
```

ウェイト中に開始された TRAN Bは、select文は成功し、update文が競合エラーとなります。
```
メッセージ 3960、レベル 16、状態 2、行 9
更新の競合により、スナップショット分離トランザクションが中断しました。スナップショット分離を使用してデータベース 'readcommited_snapshot_db' のテーブル 'dbo.sample1' に直接または間接的にアクセスし、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。トランザクションを再試行するか、更新/削除ステートメントの分離レベルを変更してください。
```

なお、update文を削除すれば成功しますが selectではTRAN Aでの更新前の値が取得されます。

SQL Serverでは デフォルトの状態のデータベースは READ_COMMITEDトランザクションなので、
スナップショットを有効にしていない場合で、`SET TRANSACTION ISOLATION LEVEL~`を消したSQLを試せば
TRAN Aのウエイト中に開始したTRAN Bのselect文(updateではありません)で待ち状態になり、TRAN Aのコミット後にTRAN Bはupdateも含め成功します。

ところで、SQL Serverで `Select ~ For Update`って トランザクションのロックが勝つ(というか優先されるというか)ので、効果が感じられなかった気がするんですが( `WITH(UPDLOCK)` を代わりに使うような気が )、今は違うんでしょうか?