[WLS] Part 2 - 12c Database and WLS - Application continuity

原文はこちら。
https://blogs.oracle.com/WebLogicServer/entry/part_2_12c_database_and

既にWebLogic ServerがOracle Database 12cをサポートすること、Application Continuity(AC)の前提条件についてエントリをまとめています。
Part 1 - 12c Database and WLS - Overview
https://blogs.oracle.com/WebLogicServer/entry/part_1_12c_database_and
http://orablogs-jp.blogspot.jp/2013/07/part-1-12c-database-and-wls-overview.html
Using Oracle JDBC Type Interfaces
https://blogs.oracle.com/WebLogicServer/entry/using_oracle_jdbc_type_interfaces
http://orablogs-jp.blogspot.jp/2013/07/using-oracle-jdbc-type-interfaces.html
接続でエラーが発生する場合、別の接続で処理を継続できるとよい-これがACの機能です。単一ノードのデータベースの場合、別の接続を取得することは、データベースとネットワークがまだ健在、つまり単なるネットワークの不調を意味しますが、Real Application Clusters(RAC)の場合、あるインスタンスで接続を失ったとしても、同じデータベースの別のインスタンスの接続を取得することができます。この機能が正しく動作するためには、エラーの前にその接続で実施したことすべてが新しい接続で再実行されることを保証することが必要です。つまり、これがACをreplayと呼ぶ理由です。オペレーションを再実行するため、当該接続で実施したオペレーションのリストを維持し、再実行できるようにする必要があります。もちろん、オペレーションを再実行する場合、最終更新からデータが変わる可能性があります。そのため、結果の追跡を続け、結果の一致を確認する必要があります。そのため、オペレーションの再実行が失敗すると、ACは失敗する可能性があります。

詳細は以下のドキュメント、ACのホワイトペーパー、データベースのドキュメントにあります。この記事ではACの機能概要を説明すると共に、ドキュメント類で取り扱っていない情報をご紹介します。
Administering JDBC Data Sources for Oracle WebLogic Server
Advanced Configurations for Oracle Drivers and Databases
http://docs.oracle.com/middleware/1212/wls/JDBCA/ds_oracledriver.htm#CCHHGCBE
Oracle Database 12c Application Continuity for Java
http://www.oracle.com/technetwork/database/application-development/applicationcontinuityforjava-1965585.pdf
Oracle® Database Development Guide 12c Release 1 (12.1)
Ensuring Application Continuity
http://docs.oracle.com/cd/E16655_01/appdev.121/e17620/adfns_app_continuity.htm#BABDJGDI
この機能を使うためには、Oracle Database 12cのJDBCドライバとDatabase 12cが必要です。11.2.0.3のドライバ、Database 11gR2 (11.2.0.3)を使う場合、動作するようにみえますが、再実行(replay)は読み取り専用トランザクションの場合のみ発生します(11gモードはサポートされていませんが、これを避けるメカニズムはありません)。

データベースサービスをACが使えるように構成する必要があります。このためには、新しい12cサービス属性である、FAILOVER_TYPE=TRANSACTIONとCOMMIT_OUTCOME=trueをサーバー側で設定する必要があります。

WebLogic ServerでACを使えるようにする手間は、利用するJDBCドライバを変えるだけです。具体的には、データソースを構成する際に、"oracle.jdbc.OracleDriver"ではなく、"oracle.jdbc.replay.OracleDataSourceImpl"を使います。それ以外、アプリケーションへの変更は一切ありません。WebLogic Serverの内部で、接続を取得すると、オペレーションの収集を開始するAPIを呼びだし、接続を閉じるとオペレーションの履歴をクリアするAPIを呼び出します。

簡単で完璧そうですね。何か裏があるのでしょうか。具象クラスの参照をやめて、新しいOracleインターフェースの利用が必要であることを取り除き、既にお伝えしました。あるアプリケーションにとっては重要な作業になる可能性があります。オペレーションの再実行が失敗したり一貫性がない場合にはACが失敗することをお伝えしました。ACが無効になる場合がほかにもあります。詳細はドキュメントをご覧頂くとして、大きなものの一つは、(少なくとも現時点では)XAトランザクションでreplayを使えない、ということです。また、2個の欠陥、ACはOracleプロキシ認証との組み合わせでは動作しないということ、そして新しいDRCP(Database Resident Connection Pooling / データベース常駐接続プーリング)機能と組み合わせでは動作しない、という欠陥を追跡しています。

WebLogic Serverでは、接続ラベル機能を使用するアプリケーションのためのラベリングコールバックを導入しました。このコールバックが登録されている場合、新しい接続がreplay前に初期化されると、このコールバックが呼び出されます。ラベルを使用しない場合でも、まだ呼びだされることを期待しているかもしれないので、replayのための新しい接続の初期化コールバックがあります(両方が存在する場合、ラベリングコールバックが初期化に優先します)。

別の考慮すべきより複雑なトピックがあります(現在WebLogic Serverのドキュメントには記載がありません)。デフォルトでは、ローカルトランザクションがその接続で完了すると、、replayは終了します。その接続で作業を続けることができますが、その時点以後で障害が発生すると、アプリケーションにエラーが返ります。このデフォルト振る舞いはサービス属性SESSION_STATE_CONSISTENCYの値がDYNAMICになっているためです。アプリケーションがトランザクション内で非トランザクションセッション状態(NTSS)を変更しない場合は、サービス属性SESSION_STATE_CONSISTENCYの値をSTATICに設定することができます。この罠に陥るアプリケーションがどれほどの数になるかわかりませんが、安全のためには、デフォルトのDYNAMICにしておくことです。

ACはすべてをreplayしませんので、エラー処理や、利用者にエラーを返すようなアプリケーションロジックを作っておく必要は依然としてあります。また、再実行のためのデータを保持するために時間、メモリに少々オーバーヘッドも発生します。それでも、JDBCドライバ名以外は変更する必要がなく、エンドユーザーにエラーを見せなくてよく、リカバリのロジックを簡素化できることから、多くのアプリケーションにとってすばらしい機能のように思えます。

P.S.
NTSSについて困惑していますか?私もそうでした。ランタイムで変更できる非トランザクショナルなセッション状態の例として、ALTER SESSION、PL/SQLのグローバル変数、SYS_CONTEXT関数、一時表のコンテンツがあります。以下にPL/SQLのグローバル変数の例を挙げました。以下の本体部分を持つパッケージを想像してみてください。
current_order number := null;
 current_line number;
 procedure new_order (customer_id number) is
  current_order := order_seq.nextval;
  insert into orders values (current_order, customer_id);
  current_line := 0;
 end new_order;
 procedure new_line (product_id number, count number) is
  current_line := current_line + 1;
  insert into order_lines values (current_order, current_line,product_id, count);
 end new_line;
end order;
WebLogic Serverにおける疑似コードシーケンスは以下のようになります。
getConnection()
exec "begin order.new_order(:my_customer_id); end;"
commit;
exec "begin order.new_line(:my_product_id, :my_count); end;"
<DB server failure and failover>
commit;
このシナリオでは、最初のトランザクションをreplayしません。それは既にコミットされており、データベースでは2個の注文で終わるためです。しかし、replayしない場合、order_idを失うため、new_lineの呼びだしに失敗するでしょう。そのため、コミット後のreplayは無効にする必要があります。このようなシナリオが存在しないことを保証できるのであれば、サービスのセッション状態を静的なものとしてマークすることができます。

0 件のコメント:

コメントを投稿