都内で働くSEの技術的なひとりごと / Technical soliloquy of System Engineer working in Tokyo

都内でサラリーマンやってます。SQL Server を中心とした (2023年からは Azure も。) マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。英語の勉強のため、英語の

SNAPSHOT トランザクションと RCSI トランザクションの違いについて実験してみる

 SNAPSHOT トランザクションと RCSI トランザクションの違いについて実験です。まず、SNAPSHOT トランザクションからです。( AdventureWorks2012 で実験しています。 ) SNAPSHOT トランザクションを有効にするには、下記の DDL 文を実行します。

ALTER DATABASE [AdventureWorks2012] SET ALLOW_SNAPSHOT_ISOLATION ON

下記の2つのクエリで実験してみましょう。

クエリ①

/*[1]*/ BEGIN TRANSACTION
/*[2]*/ UPDATE [Person].[AddressType] SET NAME = 'Billing2' WHERE AddressTypeID = 1
/*[3]*/ COMMIT TRAN

クエリ②

/*[1]*/ SET TRANSACTION ISOLATION LEVEL SNAPSHOT
/*[2]*/ BEGIN TRANSACTION
/*[3]*/ SELECT * FROM [Person].[AddressType] WHERE AddressTypeID = 1
/*[4]*/ SELECT * FROM [Person].[AddressType] WHERE AddressTypeID = 1
/*[5]*/ COMMIT TRAN
/*[6]*/ SELECT * FROM [Person].[AddressType] WHERE AddressTypeID = 1

 SQL Server Management Studio で実行していきます。下記の順番で実行していきましょう。

  1. クエリ① - [1]
  2. クエリ② - [1]
  3. クエリ① - [2]
  4. クエリ② - [2],[3]:実行結果は下記の通りです。クエリ① - [2] は反映されていません。

    f:id:koogucc11:20131007234124j:plain

  5. クエリ① - [3]
  6. クエリ② - [4]:実行結果は下記の通りです。クエリ① - [2] は反映されていません。f:id:koogucc11:20131007234124j:plain
  7. クエリ② - [5]
  8. クエリ② - [6]:実行結果は下記の通りです。クエリ① - [2] は反映されています。f:id:koogucc11:20131007233421j:plain

 次に、RCSI トランザクションを実験してみましょう。SQL Server Management Studio で実行していきます。SNAPSHOT トランザクションと同じ順序で実行していきましょう。RCSI トランザクションを有効にするには、下記の DDL 文を実行する必要があります。

ALTER DATABASE [AdventureWorks2012] SET READ_COMMITED_SNAPSHIT ON
  1. クエリ① - [1]
  2. クエリ② - [1]
  3. クエリ① - [2]
  4. クエリ② - [2],[3]:実行結果は下記の通りです。クエリ① - [2] は反映されていません。

    f:id:koogucc11:20131007234124j:plain

  5. クエリ① - [3]
  6. クエリ② - [4]:実行結果は下記の通りです。クエリ① - [2] は反映されています。f:id:koogucc11:20131007233421j:plain
  7. クエリ② - [5]
  8. クエリ② - [6]:実行結果は下記の通りです。クエリ① - [2] は反映されています。f:id:koogucc11:20131007233421j:plain
  • スナップショットトランザクション
    トランザクションの各ステートメントで、トランザクション全体で一貫性のあるデータを読み取るように指定します。このデータは、トランザクション開始時点に存在したデータです。 データの変更は、トランザクションの開始前にコミットされたものだけが認識されます。 現在のトランザクションが開始されてから他のトランザクションによってデータが変更されても、現在のトランザクションで実行されるステートメントではデータの変更は認識されません。 このオプションでは、トランザクションの各ステートメントにおいて、トランザクションの開始時点でコミットされていたデータのスナップショットを取得するのと同じ効果が得られます。
  • RCSI トランザクション
    RCSI でのトランザクションの考え方は、通常の Read Committed 分離の場合と同じです。ただし、リーダー クエリでは、競合するライターが完了するまでブロックされるのではなく、必ずクエリ開始時のデータを参照する点が異なります。このため、 RCSI を有効にして実行する場合でもアプリケーションを変更する必要がなく、動作は同じです。しかし、 REPEATABLE READ が必要なトランザクション、または HOLDLOCK を指定する SELECT が必要なトランザクションにはロックが要求され、同時実行しているライターによってブロックされることがあります。また、 SQL Server 2005 で導入されたスナップショット分離レベル機能でも行のバージョン管理を使用しますが、この機能と RCSI を混同しないでください。

以上です。