ストアド プロシージャ、トリガー、およびユーザー定義関数

適用対象: NoSQL

Azure Cosmos DB では、言語が統合された JavaScript によるトランザクション実行が行えます。 Azure Cosmos DB で NoSQL 用 API を使用する場合、ストアド プロシージャトリガーユーザー定義関数 (UDF) を JavaScript 言語で記述できます。 データベース エンジン内で実行されるロジックを JavaScript で記述することができます。 トリガー、ストアド プロシージャ、UDF は、Azure portalAzure Cosmos DB の JavaScript 言語統合クエリ API、または Azure Cosmos DB for NoSQL クライアント SDK を使用して作成および実行できます。

サーバー側プログラミングを使用する利点

JavaScript でストアド プロシージャ、トリガー、ユーザー定義関数 (UDF) を記述することにより、機能の豊富なアプリケーションを構築することができます。また、次のような利点もあります。

  • 手続き型のロジック: JavaScript は、高水準プログラミング言語であり、ビジネス ロジックを表現するためのよく知られた優れたインターフェイスを提供します。 データ上で複雑な一連の操作を実行できます。

  • アトミックなトランザクション: 単一のストアド プロシージャまたはトリガー内で実行される Azure Cosmos DB データベース操作はアトミックです。 このアトミック機能により、アプリケーションは、関連する操作を 1 つのバッチに結合できます。それらの操作すべてが成功するか、またはすべてが成功しないかのどちらかになります。

  • パフォーマンス: JSON データは、もともと JavaScript 言語の型システムにマップされています。 このマッピングにより、バッファー プール内の JSON ドキュメントの遅延実体化のようないくつかの最適化を行い、それらを必要に応じて実行コードで利用することが可能になります。 ビジネス ロジックをデータベースにシフトすることには、次のような他のパフォーマンス上のメリットがあります。

    • バッチ処理: 挿入などの操作をグループ化して、それらを一括送信できます。 ネットワーク トラフィックの待機時間コストと、別個のトランザクションの作成に伴う格納オーバーヘッドが大幅に削減されます。

    • プリコンパイル: ストアド プロシージャ、トリガー、UDF は、それぞれのスクリプトの呼び出し時のコンパイル コストを回避するために、暗黙的にバイト コード形式にプリコンパイルされます。 プリコンパイルにより、ストアド プロシージャの呼び出しが高速になり、フットプリントが小さくなります。

    • シーケンス処理: 1 つまたは複数のデータへの更新を実行するトリガーを起動するメカニズムが操作で必要になる場合があります。 アトミックな特性を備えていることに加えて、サーバー側で実行する際にパフォーマンス上の利点があります。

  • カブセル化: ストアド プロシージャを使用して、ロジックを 1 か所にグループ化できます。 カプセル化により、データの上に抽象化レイヤーが追加されるため、データとは独立してアプリケーションを進化させることができます。 データにスキーマがなく、アプリケーションに直接ロジックを追加することを管理する必要がない場合に、この抽象化のレイヤーが役に立ちます。 この抽象化により、スクリプトからのアクセスを合理化してデータのセキュリティを保つことができます。

ヒント

ストアド プロシージャは、書き込みが多く、パーティション キー値によるトランザクションが必要な操作に最適です。 ストアド プロシージャを使用するかどうかを決定する際に、書き込み可能な最大量をカプセル化するように最適化します。 一般的に、ストアド プロシージャは、大量の読み取り操作を行うのに最も効率的な手段ではありません。そのため、クライアントに返すために大量の読み取りまたはクエリを行うバッチ処理でストアド プロシージャを使用しても、期待どおりのメリットは得られません。 最適なパフォーマンスを実現するには、Azure Cosmos DB SDK を使用して、これらの読み取りが多い操作をクライアント側で実行する必要があります。

Note

ストアド プロシージャ、トリガー、ユーザー定義関数を含むサーバー側 JavaScript 機能では、モジュールのインポートはサポートされていません。

トランザクション

一般的なデータベースにおけるトランザクションは、作業の単一の論理単位として実行される一連の操作として定義されます。 各トランザクションは、ACID プロパティの保証を提供します。 ACID とは、Atomicity (アトミック性)、Consistency (一貫性)、Isolation (分離性)、Durability (持続性) を表すよく知られた頭字語です。

  • 原子性は、トランザクション内で実行されるすべての操作が単一の単位として扱われることを保証します。その結果は、そのすべてがコミットされるか、まったくコミットされないかのどちらかになります。

  • 一貫性は、トランザクションにまたがってデータが常に有効な状態にあることを保証します。

  • 分離性は、2 つのトランザクションが互いに干渉しないことを保証します。多くの商用システムは、アプリケーションのニーズに基づいて使用できる複数の分離性レベルを提供します。

  • 持続性は、データベース内でコミットされたすべての変更が常に保持されることを保証します。

Azure Cosmos DB では、JavaScript ランタイムはデータベース エンジン内にホストされます。 したがって、ストアド プロシージャおよびトリガー内で発生した要求は、データベース セッションと同じスコープで実行されます。 この機能により、Azure Cosmos DB では、ストアド プロシージャまたはトリガーに属するすべての操作の ACID プロパティが保証されます。 たとえば、トランザクションの実装方法に関する記事をご覧ください。

ヒント

Azure Cosmos DB for NoSQL でのトランザクション サポートについては、任意のクライアント SDK を使用してトランザクション バッチを実装することもできます。 詳細については、「Azure Cosmos DB for NoSQL でのトランザクション バッチ操作」を参照してください。

トランザクションのスコープ

ストアド プロシージャは Azure Cosmos DB コンテナーに関連付けられており、ストアド プロシージャの実行は論理パーティション キーにスコープが設定されています。 ストアド プロシージャには、トランザクションのスコープの論理パーティションが定義されている論理パーティション キー値を、実行時に含める必要があります。 詳細については、Azure Cosmos DB でのパーティション分割に関する記事を参照してください。

コミットとロールバック

トランザクションは、Azure Cosmos DB JavaScript プログラミング モデルにもともと統合されています。 JavaScript 関数内では、1 つのトランザクションの下ですべての操作が自動的にラップされます。 例外が発生することなくストアド プロシージャの JavaScript のロジックが完了すると、トランザクション内のすべての操作がデータベースに対してコミットされます。 BEGIN TRANSACTIONCOMMIT TRANSACTION のようなステートメント (リレーショナル データベースでよく使用される) は、Azure Cosmos DB では暗黙的です。 スクリプトからの例外がある場合、Azure Cosmos DB の JavaScript ランタイムにより、トランザクション全体がロール バックされます。 このように、Azure Cosmos DB では、例外のスローは実質的に ROLLBACK TRANSACTION と同等です。

データの一貫性

ストアド プロシージャとトリガーは、常に Azure Cosmos DB コンテナーのプライマリ レプリカ上で実行されます。 この機能により、ストアド プロシージャからの読み取りで強固な一貫性が保証されます。 ユーザー定義関数を使用したクエリはプライマリ レプリカまたは任意のセカンダリ レプリカ上で実行できます。 ストアド プロシージャとトリガーは、トランザクションの書き込みをサポートすることを目的としています。 一方で、読み取り専用のロジックは、アプリケーション側のロジックとして実装するのが最適です。また Azure Cosmos DB for NoSQL SDK を使用するクエリは、データベース スループットを飽和状態にするのに役立ちます。

ヒント

ストアド プロシージャまたはトリガー内で実行されるクエリからは、同じスクリプトのトランザクションによって行われた項目の変更を確認できない場合があります。 このステートメントは、SQL クエリ (getContent().getCollection().queryDocuments() など) だけでなく、統合言語クエリ (getContext().getCollection().filter()など) にも適用されます。

制限された実行

すべての Azure Cosmos DB 操作は、特定の要求タイムアウト期間内に終了する必要があります。 ストアド プロシージャには、5 秒のタイムアウト制限があります。 この制約は、JavaScript 関数 (ストアド プロシージャ、トリガー、およびユーザー定義関数) に適用されます。 この制限時間内に操作が完了しなかった場合、トランザクションはロール バックされます。

JavaScript 関数が制限時間内に完了するか、実行をバッチ処理または再開するための継続ベースのモデルを実装するようにできます。 時間制限を処理するストアド プロシージャとトリガーの開発を容易にするために、Azure Cosmos DB コンテナーで実行するすべての関数 (項目の作成、読み取り、更新、削除など) は、その操作が完了するかどうかを表すブール値を返します。 この値が false の場合、スクリプトが構成した値よりも長い時間またはプロビジョンしたスループットを消費しているため、プロシージャが実行を終了する必要があることを示します。 最初の受け付けられていない格納操作の前にキューに入れられた操作は、ストアド プロシージャが時間内に完了し追加の要求がキューに入れられない限り、終了することが保証されます。 そのため、スクリプトの制御フローを管理する JavaScript のコールバック規則を使用して操作を一度に 1 つずつキューに入れる必要があります。 スクリプトは、サーバー側の環境で実行されるため、厳密に管理されます。 繰り返し実行境界に違反するスクリプトは、非アクティブとしてマークされる場合があり、実行できません。そのようなスクリプトは実行境界を守るように再作成する必要があります。

JavaScript 関数は、プロビジョニングされているスループット容量にも影響を受けます。 JavaScript 関数は潜在的に短い時間内に大量の要求ユニットを消費する可能性があり、プロビジョニングされているスループット容量の制限に達した場合はレートが制限されます。 これらのデータベース操作は、クライアントから同じ操作を実行するよりも少し安価に行えますが、スクリプトが実行中のデータベース操作に費やされたスループットに加え、追加のスループットを消費することに注意してください。

トリガー

Azure Cosmos DB では 2 種類のトリガーがサポートされます。

プリトリガー

Azure Cosmos DB には、Azure Cosmos DB 項目で操作を実行することによって呼び出されるトリガーが用意されています。 たとえば、項目を作成するときにプリトリガーを指定できます。 この場合、プリトリガーは、項目が作成される前に実行されます。 プリトリガーは入力パラメーターを持つことができません。 必要に応じて、要求オブジェクトを使用して、元の要求からのドキュメント本文を更新できます。 トリガーが登録されたら、ユーザーは実行できる操作を指定できます。 トリガーが TriggerOperation.Create によって作成される場合、置換操作でのこのトリガーの使用は許可されません。 例については、「トリガーを書き込む方法」の記事を参照してください。

ポストトリガー

プリトリガーと同様に、ポストトリガーも Azure Cosmos DB 項目に対する操作に関連付けられており、入力パラメーターは必要ありません。 ポストトリガーは、操作が完了した 後に 実行され、クライアントに送信される応答メッセージにアクセスします。 例については、「トリガーを書き込む方法」の記事を参照してください。

Note

登録されたトリガーは、対応する操作 (作成/削除/置換/更新) が発生しても自動的には実行されません。 これらの操作を実行するときに明示的に呼び出す必要があります。 詳細については、トリガーの実行方法に関する記事を参照してください。

ユーザー定義関数

ユーザー定義関数 (UDF) は、NoSQL 用 API クエリ言語の構文を拡張してカスタム ビジネス ロジックを簡単に実装するために使用します。 これらは、クエリ内でのみ呼び出すことができます。 UDF は、コンテキスト オブジェクトにアクセスできず、計算のみの JavaScript として使用する必要があります。 したがって、UDF はセカンダリ レプリカで実行できます。

JavaScript 統合言語クエリ API

NoSQL 用 API クエリ構文を使ってクエリを発行するほか、サーバー側の SDK では、SQL の知識がなくても、JavaScript インターフェイスを使用してクエリを実行できます。 JavaScript クエリ API では、述語関数を一連の関数呼び出しに渡すことでクエリをプログラムで作成できます。 クエリは JavaScript ランタイムで解析され、Azure Cosmos DB 内で効率的に実行されます。 JavaScript クエリ API サポートの詳細については、JavaScript 言語統合クエリ API の操作に関する記事を参照してください。 たとえば、JavaScript クエリ API を使用してストアド プロシージャおよびトリガーを記述する方法に関する記事を参照してください。

次のステップ

Azure Cosmos DB のストアド プロシージャ、トリガー、およびユーザー定義関数の記述方法および使用方法については、以下の記事を参照してください。

Azure Cosmos DB への移行のための容量計画を実行しようとしていますか? 容量計画のために、既存のデータベース クラスターに関する情報を使用できます。