[JavaScript, Database] node-oracledb 3.0 Introduces SODA Document Storage

原文はこちら。
https://blogs.oracle.com/opal/node-oracledb-30-introduces-soda-document-storage

Release announcement:

Node-oracledb 3.0.0(Oracle DatabaseへアクセスするためのNode.js用モジュール)がnpmからご利用いただけるようになりました。
node-oracledb version 3.0
https://www.npmjs.com/package/oracledb

Top features:

  • Simple Oracle Document Access (SODA) (プレビュー)
  • 接続プールの廃棄
  • Callタイムアウト
Node-oracledb 3がリリースされました。このリリースではいくつかのOracle DatabaseおよびOracle Client 18cの機能をサポートしています。
以前のバージョンのように、node-oracledb 3はOracle Clientライブラリ11.2以降と組み合わせて利用できますので、クライアントバージョンに依存しますが、Oracle Database 9.2以後と接続できるようになります。ただ、Oracle Client 18.3ライブラリを使ってOracle Database 18.3と接続している場合のみ、最新のすばらしい一連のOracle Databaseの機能を利用できます。
node-oracledb 3.0でのトピックをご紹介しましょう。
  • Oracle Simple Document Access (SODA) のサポート:標準のリレーショナルアクセスモデルに加わったのが、Oracle SODAの新しいAPIです。例を使って後で説明します。
  • pool.close() の新しい引数drainTimeを使うと、指定した秒数が経過したらプールを強制的にクローズできます。この機能はDanilo Silvaの貢献によるものです。
    pool.close()
    https://github.com/oracle/node-oracledb/blob/master/doc/api.md#poolclose
    プールを指定したdrainTimeでクローズすると、後続のgetConnection()の呼び出しは失敗しますが、現在利用している接続は引き続き機能し続けます。これにより、コードの完了と未解決のトランザクションのコミットが可能になります。接続が使用されていない場合、またはドレイン時間到達時のいずれか最初に発生したタイミングで、プールとすべての接続を強制的にクローズします。

    「強制的にクローズ」という言葉は厳しく思われますが、実際には、ユーザーは接続プールがクローズ中、もしくはすでにクローズされているという明確なメッセージを得るため、ドレーン時間によってアプリケーションの正常終了が可能ですし、タイムアウトを待たずにデータベース側のセッションをきれいに解放することができます。drainTimeはゼロにすることもできるので、すべてのセッションを即座に終了できます。これは、データベースにとって都合よいようにアプリケーションを終了したいときに便利です。
  • 事前構築済みのnode-oracledbバイナリのインストールは、基本的なプロキシ認証のサポートによって少し楽になりました。また、プロキシ環境変数が設定されていない場合、インストール時に 'npm config'プロキシ値を使用するようになりました。これらの変更はCemre Menguの貢献によるものです。
  • 長時間実行されているデータベース呼び出しを中断するconnection.callTimeoutプロパティを追加しました。これは、Oracle Databaseのバージョンに関係なく、node-oracledb 3とOracle Clientライブラリのバージョン18.1以降を組み合わせて使用している場合に使用できます。
    connection.callTimeout
    https://oracle.github.io/node-oracledb/doc/api.html#propconncalltimeout
    呼び出しタイムアウトは制御不能なSQLやPL/SQL文の実行を防止する上で有用なものです。背景として、node-oracledbの実行の下にあるメインコード層はOracle Call Interfaceで、このAPIはOracle Databaseへの全てのネットワーク接続を処理します。node-oracledbが各OCI関数を呼び出すと、ゼロ回以上のDatabaseとのやりとり、つまりデータベースの呼び出しと戻ってくるレスポンスの取得というが発生します。

    callTimeout値は、各ラウンドトリップに個別に適用され、すべてのラウンドトリップの合計に適用されるわけではありません。各ラウンドトリップの完了前または終了後のnode-oracledbでの処理時間は対象外です。
    • とある1回のラウンドトリップの開始から、当該ラウンドトリップの完了までの時間がcallTimeoutミリ秒を超える場合、オペレーションを停止して、エラーを返します。
    • node-oracleledbのオペレーションで複数回のラウンドトリップが必要で、各ラウンドトリップがcallTimeoutミリ秒より短い時間の場合、すべてのラウンドトリップの合計がcallTimeoutを超えていても、タイムアウトは発生しません。
    • ラウンドトリップの必要がない場合、オペレーションは中断されません。
    callTimeoutミリ秒を超過すると、node-oracledbは内部接続状態をクリーンアップしようとします。このクリーンアップには、別のcallTimeoutミリ秒が適用されます。
  • クリーンアップが成功した場合、以下のエラーメッセージが返りますが、アプリケーションは引き続き接続を利用できます。
    "DPI-1067: call timeout of N ms exceeded with ORA-XXX"
    callTimeoutの値が小さい場合、追加のcallTimeout期間内に接続のクリーンアップが正常に完了しないことがあります。 この場合、ORA-3114が戻され、接続は使用できなくなり、接続を閉じる必要があります。
  • Windowsの場合、node-oracledbは、まず 'node_modules\oracledb\build\Release' ディレクトリからOracle Clientライブラリをロードしようとします。その後、標準のWindowsライブラリディレクトリ検索、つまり環境変数PATHで定義されたディレクトリからロードしようとします。

    この新機能は、Windowsにアプリケーションをバンドルし、Oracle Instant Clientを含める場合に便利です。つまり、クライアントライブラリを 'node_modules\oracledb\build\Release' ディレクトリに置くことでPATHの設定が不要になり、PATHを変更するユーザーを心配する必要がなくなり、PATHに複数のバージョンのOracle Clientライブラリがあっても心配する必要がないからです。
  • poolPingInterval機能は、Oracle Clientライブラリ12.2以降で接続プールを使用している場合に「再有効化」されています。ネットワークが切断されたかどうかを確認するのにOracle Clientの内部チェックが非常に効率的ゆえ、以前はこれらのバージョンでは意図的に有効になっていませんでした。しかし、データベース・セッション・リソース制限(例えば、使用時にORA-02396が返される)を超えたり、DBAによって明示的にクローズ(たとえば、ORA-00028が返される)されたりしたために利用不可になった接続は、内部チェックでは識別できません。ここで、poolPingIntervalが役に立ちます。
    oracledb.poolPingInterval
    https://oracle.github.io/node-oracledb/doc/api.html#propdbpoolpinginterval
    この変更により、アプリの可用性は高まるように見えますが、欠点もあります。アプリが黙って再接続している可能性がありますし、大きなプールを再構築する必要がある場合は、接続ストームに気付かない可能性があります。AWRレポートをチェックして接続が頻繁に発生しているかどうかを監視し、アイドル・セッションを終了しないようにネットワークおよびDBA管理者と協力して作業する必要があります。
その他の変更や機能改善は変更履歴をご覧ください。
Change Log
https://github.com/oracle/node-oracledb/blob/master/CHANGELOG.md
といいつつ、SODAについて説明をしますので、是非この後もお読みください。

Simple Oracle Document Access (SODA) in node-oracledb

Oracle Simple Document Access(SODA)はNoSQLスタイルのAPIのセットで、SQLを知らなくても、Oracle Databaseにドキュメント(特にJSON)のコレクションを作成および格納したり、取得や問合せを実行できます。Oracle Database 18.3およびOracle Client 18.3以上を使用している場合、node-oracledb 3でSODAサポートを利用できます。SODA APIは、Python、C、Java、PL/SQL、RESTで利用できるため、幅広くアクセスできるため、きっとお手元のデータツールキットの中でも有用なツールとなることでしょう。現在、node-oracledb 3 SODA APIは「プレビュー」扱いですが、Oracle Clientライブラリの将来のバージョンで変更される予定です。
node-oracledbのクラス図から、リレーショナルの世界とSODAの世界の分離がわかると思います。

現実には、SODAはOracle Databaseの表に基づいているので、セキュアで効率的なストレージ・ソリューションを提供します。これらの表にはSQLでアクセスできますが、ほとんどその必要はありません。それが必要なのは、レポート作成のための分析などの高度なOracle Database機能を使う場合だけでしょう。
代わりに、新しいクラスとメソッドを使います。DBAがSODA_APP権限を付与すると、その中にコレクションを作成したり、ドキュメント(JSONなど)を格納したりできます。いくつかの基本的なサンプルをご紹介します。
// Create the parent object for SODA.
soda = await connection.getSodaDatabase();

// Create a new SODA collection, if it doesn't exist.
// This will open an existing collection, if the name is already in use.
collection = await soda.createCollection("mycollection");

// Insert a document.
// A system generated key is created by default.
content = {name: "Matilda", address: {city: "Melbourne"}};
doc = await collection.insertOneAndGet(content);
key = doc.key;
console.log("The key of the new SODA document is: ", key);
キー・ルックアップや検索を使ってドキュメントを取得できます。キー・ルックアップは簡単です。
// Fetch the document back
doc = await collection.find().key(key).getOne(); // A SodaDocument
content = doc.getContent();                      // A JavaScript object
console.log('Retrieved SODA document as an object:');
console.log(content);
JSONに変換可能なドキュメントの場合、文字列として取得できます。
content = doc.getContentAsString();              // A JSON string
console.log('Retrieved SODA document as a string:');
console.log(content);
メソッドfind()はオペレーション・ビルダで順々に制限基準を設定できるので、一連のドキュメントの個数を減らした後に、getOne()getDocuments()count()などの終端メソッドが作用します。
JSONドキュメントでは、完全なフィルタリング仕様言語を使用してQBE(Query-by-Example)でドキュメントを検索できます。 以下は簡単な例です。
// Find all documents with city names starting with 'S'
documents = await collection.find()
  .filter({"address.city": {"$like": "S%"}})
  .getDocuments();

for (let i = 0; i < documents.length; i++) {
  content = documents[i].getContent();
  console.log('  city is: ', content.address.city);
}
実行可能なサンプルはsoda1.jsにあります。
soda1.js
https://github.com/oracle/node-oracledb/tree/master/examples/soda1.js#L34
node-oracledbのマニュアルのSODAのセクションとIntroduction to Simple Oracle Document Access(SODA)のマニュアルで、そのパワーとシンプルさを確認してください。
Simple Oracle Document Access (SODA)
https://oracle.github.io/node-oracledb/doc/api.html#sodaoverview
Oracle® Database Simple Oracle Document Access (SODA)の概要 18c
SODAの概要
https://docs.oracle.com/cd/E96517_01/adsdi/overview-soda.html#GUID-BE42F8D3-B86B-43B4-B2A3-5760A4DF79FBOracle® Database Introduction to Simple Oracle Document Access (SODA) 18c
Overview of SODA
https://www.oracle.com/pls/topic/lookup?ctx=dblatest&id=GUID-BE42F8D3-B86B-43B4-B2A3-5760A4DF79FB
まだOracle Database 18.3の環境をお持ちではありませんか?なら、こちらからどうぞ。
Oracle Database Software Downloads
https://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html
もしくは旧バージョンのOracle DatabaseでのJSONの利用にご興味があれば、こちらをどうぞ。
So you want to use JSON in Oracle Database with Node.js?
https://blogs.oracle.com/opal/so-you-want-to-use-json-in-oracle-database-with-nodejs

Summary

あなたの開発体験をより良いものにするために、node-oracledbに重要な機能を引き続き導入していきます。Wishlistにたくさん詰まっているため、引き続き作業を続けます。コミュニティからの貢献ははいつでも歓迎します。そして、node-oracledbの今リリースおよび以前のリリースの改善を手助けしてくれた方々に感謝いたします。

Resources

0 件のコメント:

コメントを投稿