

# Babelfish でのトランザクション分離レベル
<a name="babelfish-transaction"></a>

Babelfish は、トランザクション分離レベルとして `READ UNCOMMITTED`、`READ COMMITTED`、`SNAPSHOT` をサポートしています。Babelfish 3.4 バージョン以降、追加の分離レベルとして `REPEATABLE READ` と `SERIALIZABLE` をサポートしています。Babelfish のすべての分離レベルは、PostgreSQL の対応する分離レベルの動作でサポートされています。SQL Server と Babelfish では、トランザクション分離レベル (同時アクセスのブロック、トランザクションによって保持されるロック、エラー処理など) を実装するための基盤となるメカニズムが異なります。また、同時アクセスがワークロードによってどのように機能するかには微妙な違いがいくつかあります。この PostgreSQL の動作の詳細については、「[トランザクション分離](https://www.postgresql.org/docs/current/transaction-iso.html)」を参照してください。

**Topics**
+ [トランザクション分離レベルの概要](#babelfish-transaction.overview)
+ [トランザクション分離レベルのセットアップ](#babelfish-transaction.setting)
+ [トランザクション分離レベルの有効化または無効化](#babelfish-transaction.enabling)
+ [Babelfish と SQL Server の分離レベルの比較](babelfish-transaction.examples.md)

## トランザクション分離レベルの概要
<a name="babelfish-transaction.overview"></a>

 元の SQL Server トランザクション分離レベルは、データのコピーが 1 つだけ存在し、クエリがアクセスする前に行などのリソースをロックする必要があるという悲観的ロックに基づいています。後で、`READ COMMITTED` 分離レベルのバリエーションが導入されました。これにより、行バージョンを使用することで、ノンブロッキングアクセスを使用するリーダーとライター間の同時実行性が向上します。さらに、`SNAPSHOT` と呼ばれる新しい分離レベルも利用できるようになりました。これも行バージョンを使用して、トランザクションの終了まで保持される読み取りデータの共有ロックを回避することで、`REPEATABLE READ` 分離レベルよりも優れた同時実行性を実現します。

SQL Server とは異なり、Babelfish のすべてのトランザクション分離レベルは楽観的ロック (MVCC) に基づいています。各トランザクションは、基になるデータの現在の状態に関係なく、ステートメントの先頭 (`READ COMMITTED`) またはトランザクションの先頭 (`REPEATABLE READ`、`SERIALIZABLE`) のいずれかでデータのスナップショットを参照します。したがって、Babelfish での同時トランザクションの実行動作は SQL Server とは異なる場合があります。

例えば、最初は SQL Server でブロックされるが、後では成功する、分離レベル `SERIALIZABLE` のトランザクションがあるとします。同じ行を読み取るまたは更新する同時トランザクションとのシリアル化の競合により、Babelfish では失敗する可能性があります。また、複数の同時トランザクションを実行すると、SQL Server と比較して Babelfish の最終結果が異なる場合もあります。分離レベルを使用するアプリケーションは、同時実行シナリオについて徹底したテストを行う必要があります。


| SQL Server の分離レベル | Babelfish 分離レベル | PostgreSQL 分離レベル | コメント | 
| --- | --- | --- | --- | 
| `READ UNCOMMITTED` | `READ UNCOMMITTED` | `READ UNCOMMITTED` | `READ UNCOMMITTED` は Babelfish または PostgreSQL の `READ COMMITTED` と同じです | 
| `READ COMMITTED` | `READ COMMITTED` | `READ COMMITTED` | SQL Server `READ COMMITTED` は悲観的ロックベースで、Babelfish `READ COMMITTED` はスナップショット (MVCC) ベースです。 | 
| `READ COMMITTED SNAPSHOT` | `READ COMMITTED` | `READ COMMITTED` | どちらもスナップショット (MVCC) ベースですが、まったく同じではありません。 | 
| `SNAPSHOT` | `SNAPSHOT` | `REPEATABLE READ` | まったく同じです。 | 
| `REPEATABLE READ` | `REPEATABLE READ` | `REPEATABLE READ` | SQL Server `REPEATABLE READ` は悲観的ロックベースで、Babelfish `REPEATABLE READ` はスナップショット (MVCC) ベースです。 | 
| `SERIALIZABLE` | `SERIALIZABLE` | `SERIALIZABLE` | SQL Server の `SERIALIZABLE` は悲観的分離であり、Babelfish の `SERIALIZABLE` はスナップショット (MVCC) ベースです。 | 

**注記**  
テーブルヒントは現在サポートされておらず、その動作は Babelfish の定義済みエスケープハッチ `escape_hatch_table_hints` を使用して制御されます。

## トランザクション分離レベルのセットアップ
<a name="babelfish-transaction.setting"></a>

トランザクション分離レベルは、次のコマンドを使用して設定します。

**Example**  

```
SET TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SNAPSHOT | SERIALIZABLE }
```

## トランザクション分離レベルの有効化または無効化
<a name="babelfish-transaction.enabling"></a>

Babelfish では、トランザクション分離レベル `REPEATABLE READ` と `SERIALIZABLE` はデフォルトで無効になっているため、`sp_babelfish_configure` を使用して `babelfishpg_tsql.isolation_level_serializable` または `babelfishpg_tsql.isolation_level_repeatable_read` エスケープハッチを `pg_isolation` に設定して明示的に有効にする必要があります。詳細については、「[エスケープハッチ処理時の Babelfish のエラー処理の管理](babelfish-strict.md)」を参照してください。

現在のセッションで `REPEATABLE READ` と `SERIALIZABLE` の使用を有効または無効にするために、それぞれのエスケープハッチを設定する例を以下に示します。オプションで、現在のセッションとそれ以降のすべての新しいセッションのエスケープハッチを設定する `server` パラメータを含めます。

 現在のセッションでのみ `SET TRANSACTION ISOLATION LEVEL REPEATABLE READ` の使用を有効にします。

**Example**  

```
EXECUTE sp_babelfish_configure 'isolation_level_repeatable_read', 'pg_isolation'
```

 現在のセッションおよび後続のすべての新しいセッションで `SET TRANSACTION ISOLATION LEVEL REPEATABLE READ` の使用を有効にします。

**Example**  

```
EXECUTE sp_babelfish_configure 'isolation_level_repeatable_read', 'pg_isolation', 'server'
```

 現在のセッションおよび後続の新しいセッションで `SET TRANSACTION ISOLATION LEVEL REPEATABLE READ` を無効にします。

**Example**  

```
EXECUTE sp_babelfish_configure 'isolation_level_repeatable_read', 'off', 'server'
```

 現在のセッションでのみ `SET TRANSACTION ISOLATION LEVEL SERIALIZABLE` の使用を有効にします。

**Example**  

```
EXECUTE sp_babelfish_configure 'isolation_level_serializable', 'pg_isolation'
```

 現在のセッションおよび後続のすべての新しいセッションで `SET TRANSACTION ISOLATION LEVEL SERIALIZABLE` の使用を有効にします。

**Example**  

```
EXECUTE sp_babelfish_configure 'isolation_level_serializable', 'pg_isolation', 'server'
```

 現在のセッションおよび後続の新しいセッションで `SET TRANSACTION ISOLATION LEVEL SERIALIZABLE` の使用を無効にします。

**Example**  

```
EXECUTE sp_babelfish_configure 'isolation_level_serializable', 'off', 'server'
```