SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

[SQL Server 2014 CTP2]自動的な SNAPSHOT 分離レベルへのエスカレーション

leave a comment

メモリ最適化テーブルへのアクセスでは、使用できるトランザクション分離レベル

  • SNAPSHOT
  • REPEATABLE READ
  • SERIALIZABLE

の 3 種類になります。

SQL Server のデフォルトのトランザクション分離レベルは READ COMMITTED になります。

 

メモリ最適化テーブルでの READ COMMITTED のサポート状況は以下のようになっています。

READ COMMITTED 分離レベルは自動コミット トランザクションのメモリ最適化されたテーブルでサポートされます。  この分離レベルは、明示的または暗黙的なユーザー トランザクションではサポートされません。 自動コミット トランザクションが有効になっている、メモリ最適化テーブルについては、クエリがどのディスク ベース テーブルにもアクセスできない場合にのみ、分離レベル READ_COMMITTED_SNAPSHOT がサポートされます。 また、解釈された Transact-SQL を使用して SNAPSHOT 分離で開始されるトランザクションでは、メモリ最適化テーブルにアクセスできません。 解釈された Transact-SQL を使用して REPEATABLE READ 分離または SERIALIZABLE 分離で開始されるトランザクションでは、SNAPSHOT 分離を使用してメモリ最適化テーブルにアクセスする必要があります。 このシナリオの詳細については、「複数コンテナーにまたがるトランザクション」を参照してください。

READ COMMITTED は、SQL Server の既定の分離レベルです。  ただし、上で説明したように、READ COMMITTED 分離レベルは自動コミット トランザクションのメモリ最適化されたテーブルでサポートされます。 この分離レベルは、明示的または暗黙的なユーザー トランザクションではサポートされません。 既定の分離レベルが READ COMMITED 以下の場合は、次のいずれかの操作を実行できます。

SQL Server では自動コミットがデフォルトですが、この自動コミットであれば READ COMMITTED はサポートされています。

ですので、以下のようなクエリは分離レベルを意識しなくても実行することが可能です。

SELECT * FROM MemTable

 

それでは、以下のような明示的なトランザクションを指定したクエリを実行してみます。

BEGIN TRAN
SELECT * FROM MemTable
COMMIT TRAN

 

この場合は以下のようなエラーが発生します。

メッセージ 41368、レベル 16、状態 0、行 2

READ COMMITTED 分離レベルを使用したメモリ最適化テーブルへのアクセスは、自動コミット トランザクションの場合にのみサポートされています。

明示的および暗黙的トランザクションの場合はいずれもサポートされません。

WITH (SNAPSHOT) などのテーブル ヒントを使用して、メモリ最適化テーブルのサポートされている分離レベルを指定してください。

 

明示的なトランザクションを指定した場合にはテーブルヒントに SNAPSHOT を設定します。

BEGIN TRAN
SELECT * FROM MemTable WITH(SNAPSHOT)
COMMIT TRAN

 

この SNAPSHOT のテーブルヒントはメモリ最適化テーブル用のヒントになります。

メモリ最適化されたテーブルは、SNAPSHOT 分離でアクセスされます。  SNAPSHOT は、メモリ最適化されたテーブルだけで使用できまます (ディスク ベースのテーブルでは使用できません)。 詳細については、「トランザクション分離レベル」を参照してください。

 

SET TRANSACTION ISOLATION LEVEL にも SNAPSHOT はありますが、こちらを使ってもメモリ最適化テーブルにはアクセスをすることはできません。

メッセージ 41332、レベル 16、状態 0、行 2

セッション TRANSACTION ISOLATION LEVEL が SNAPSHOT に設定されている場合、メモリ最適化テーブルとネイティブ コンパイル ストアド プロシージャは、アクセスすることも作成することもできません。

 

CTP1 では SNAPSHOT をテーブルヒントとして指定していましたが、CTP2 になり、ALTER DATABASE に MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT というオプションが追加されました。

デフォルトでは無効になっているのですが有効にすると以下のように動作が変わります。

トランザクション分離レベルが SNAPSHOT より低い分離レベル (たとえば、READ COMMITTED または READ UNCOMMITTEDREAD) に設定されている場合は、メモリ最適化テーブル上で解釈されたすべての Transact-SQL 操作が SNAPSHOT 分離レベルで実行されます。  この動作は、トランザクション分離レベルがセッション レベルで明示的に設定されているか、既定値が暗黙的に使用されるかに関係なく実行されます。

このオプションが有効になっている場合は自動的に分離レベルがエスカレーションされますので、明示的なトランザクションを指定した場合もテーブルヒントを指定しないでもアクセスが可能となります。

ALTER DATABASE TESTDB SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = ON
GO
BEGIN TRAN
SELECT * FROM MemTable
COMMIT TRAN

 

自動エスカレーションができると既存のクエリに手を加える箇所が少なくなりそうなので、この機能はいいですね~。

Share

Written by Masayuki.Ozawa

10月 27th, 2013 at 9:42 pm

Posted in SQL Server

Tagged with ,

Leave a Reply