Oracle® Fusion Middleware Oracle WebLogic Server JAX-WS Webサービスの開発 12c (12.2.1.2.0) E82857-02 |
|
前 |
次 |
この章の内容は次のとおりです:
WebLogic Webサービスでは、次の仕様をサポートすることで、Websphere、Microsoft .NETといった他の外部トランザクション処理システムとの相互運用性を実現しています。
Webサービスの原子性トランザクション(WS-AtomicTransaction)バージョン1.0、1.1、および1.2: http://docs.oasis-open.org/ws-tx/wstx-wsat-1.2-spec-cs-01/wstx-wsat-1.2-spec-cs-01.html
Webサービスのコーディネーション(WS-Coordination)バージョン1.0、1.1、および1.2: http://docs.oasis-open.org/ws-tx/wstx-wscoor-1.2-spec-cs-01/wstx-wscoor-1.2-spec-cs-01.html
これらの仕様は、一連の参加者の間で分散されたアクティビティを調整するための拡張フレームワークを定義するものです。次の図に示されているコーディネータは中心的なコンポーネントで、トランザクションの状態(調整コンテキスト)を管理し、Webサービスおよびクライアントを参加者として登録することを可能にします。
次の表では、この図に示されているWebサービス原子性トランザクションのコンポーネントについて説明します。
表15-1 Webサービス原子性トランザクションのコンポーネント
コンポーネント | 説明 |
---|---|
コーディネータ |
トランザクションの状態(調整コンテキスト)を管理し、Webサービスおよびクライアントを参加者として登録することを可能にします。 |
アクティブ化サービス |
アプリケーションによるトランザクションのアクティブ化、およびアクティビティの調整コンテキストの作成を可能にします。作成された調整コンテキストは、トランザクション・フローとともに渡されます。 |
登録サービス |
アプリケーションを参加者として登録することを可能にします。 |
アプリケーション・プロトコルX、Y |
サポートされている調整プロトコル(WS-AtomicTransactionなど)。 |
次の図は、Webサービス原子性トランザクションのコンテキスト内で相互に作用する2つのWebLogic Serverインスタンスを示しています。わかりやすくするために、2つのWebLogic Webサービス・アプリケーションを示しています。
次の点に注意してください。
ローカルJTAトランザクション・マネージャを使用すると、すべてWebサービス・リクエストのコンテキスト内で、トランザクションを下位トランザクションとしてローカルなJTA環境との間でインポートおよびエクスポートできます。
調整コンテキストの作成と管理は、ローカルJTAトランザクション・マネージャによって行われます。
トランザクションの整合性管理とリカバリ処理はすべて、ローカルJTAトランザクション・マネージャによって行われます。
JTAの詳細は、『Oracle WebLogic Server JTAアプリケーションの開発』を参照してください
次に、図15-2に示されているエンドツーエンドのWebサービス原子性トランザクションの相互作用の例について説明します。
アプリケーションAが、サーバーAでJTAトランザクション・マネージャを使用して、コントロールの現行スレッドに対するトランザクションを開始します。
アプリケーションAが、サーバーBのアプリケーションBでWebサービス・メソッドをコールします。
サーバーAがトランザクション情報を更新し、調整コンテキストを含むSOAPヘッダーを作成して、トランザクションおよびローカル・コーディネータを指定します。
サーバーBがアプリケーションBのリクエストを受信して、ヘッダーにトランザクション調整コンテキストが含まれていることを検出し、アプリケーションBがこのトランザクションの参加者としてすでに登録されているかどうかを判断します。すでに登録されていれば、そのトランザクションは再開され、登録されていない場合は、新しいトランザクションが開始されます。
アプリケーションBがインポート済トランザクションのコンテキスト内で実行されます。アプリケーションの対話に使用されるすべてのトランザクション・リソースは、このインポート済トランザクションに登録されます。
サーバーBが、トランザクション調整コンテキスト内で指定されている登録サービスを使用して、WS-AtomicTransactionトランザクションの参加者として自身を登録します。
サーバーAがトランザクションを再開します。
アプリケーションAが処理を再開し、トランザクションをコミットします。
ドメインの作成または拡張を行う際に、Webサービス原子性トランザクションに加えて、Webサービスのその他の高度な機能を使用する予定の場合は(すぐに使用するのか、将来使用するのかを問わず)、WebLogic Advanced Web Services for JAX-WS拡張テンプレート(wls_webservice_jaxws.jar
)を適用すると、Webサービスの高度な機能をサポートするのに必要なリソースを自動的に構成できます。この拡張テンプレートの使用は必須ではありませんが、使用すると必要なリソースの構成が格段に容易になります。あるいは、Oracle WebLogic Server管理コンソールまたはWLSTを使用して、これらの高度な機能に必要なリソースを構成できます。詳細は、「高度なWebサービス機能のためのドメインの構成」を参照してください
注意:
Webサービスのその他の高度な機能をWebサービス原子性トランザクションとともに使用する予定がない場合、この拡張テンプレートを適用する必要はなく、起動時間とメモリー・フットプリントが最小限に抑えられます。
Webサービスに対してWebサービス原子性トランザクションを有効にするには:
Javaから開始する場合(ボトムアップ)は、Webサービス・エンドポイントの実装クラスまたは実装メソッドに@weblogic.wsee.wstx.wsat.Transactional
アノテーションを追加します。詳細は、「JWSファイルでの@Transactionalアノテーションの使用」を参照してください。
WSDから開始する場合(トップダウン)は、wsdlc
を使用して既存のWSDLファイルからWebサービスを生成します。この場合、WSDLで通知されたWS-AtomicTransactionポリシー・アサーションが、wsdlc
によって生成された新しいWebサービスのWSDLファイルに送られ、その中に組み込まれます。「WSDLから開始するWebサービス原子性トランザクションの有効化」を参照してください。
デプロイメント時に、WebLogic Server管理コンソールを使用して、Webサービスのエンドポイント・レベルまたはメソッド・レベルでWebサービス原子性トランザクションを有効にして構成します。詳細は、「管理コンソールを使用したWebサービス原子性トランザクションの構成」を参照してください。
次の表は、Webサービス原子性トランザクションを有効にする際に設定可能な構成オプションをまとめたものです。
表15-2 Webサービス原子性トランザクションの構成オプション
属性 | 説明 |
---|---|
|
Webサービスおよびクライアントに対して使用されるWebサービス原子性トランザクション調整コンテキストのバージョン。クライアントの場合、アウトバウンド・メッセージに使用されるバージョンのみを指定します。指定した値は、トランザクション全体で整合性が取れている必要があります。 有効な値は、 |
|
Webサービス原子性トランザクション調整コンテキストがトランザクション・フローとともに渡されるかどうか。有効な値は、表15-3を参照してください。 |
次の表は、フロー・タイプの有効な値と、Webサービスおよびクライアントでのそれらの意味をまとめたものです。この表では、@TransactionAttribute
アノテーションを使用するEJB型のWebサービスに対してWebサービス原子性トランザクションを構成する際の有効な値の組合せも示しています。
表15-3 フロー・タイプの値
値 | Webサービス・クライアント | Webサービス | EJB @TransactionAttributeの有効な値 |
---|---|---|---|
|
JTAトランザクションがある場合: トランザクションの調整コンテキストをエクスポートしません。 JTAトランザクションがない場合: トランザクションの調整コンテキストをエクスポートしません。 |
トランザクション・フローが存在する場合: トランザクションの調整コンテキストをインポートしません。CoordinationContextヘッダーに トランザクション・フローがない場合: トランザクションの調整コンテキストをインポートしません。 |
|
|
JTAトランザクションがある場合: トランザクションの調整コンテキストをエクスポートします。 JTAトランザクションがない場合: トランザクションの調整コンテキストをエクスポートしません。 |
トランザクション・フローが存在する場合: トランザクション・コンテキストをインポートします。 トランザクション・フローがない場合: トランザクションの調整コンテキストをインポートしません。 |
|
|
JTAトランザクションがある場合: トランザクションの調整コンテキストをエクスポートします。 JTAトランザクションがない場合: 例外がスローされます。 |
トランザクション・フローが存在する場合: トランザクション・コンテキストをインポートします。 トランザクション・フローがない場合: サービス側の例外がスローされます。 |
|
Webサービス原子性トランザクションを有効にするには、Webサービス・エンドポイントの実装クラスまたは実装メソッドに@weblogic.wsee.wstx.wsat.Transactional
アノテーションを指定します。
注意:
weblogic.jws.Transactional
もアノテーション付きのクラスまたは操作をトランザクション内で確実に実行するためのものですが、この場合のトランザクションは原子性トランザクションではありませんので、このアノテーションと混同しないでください。
次の点に注意してください。
Webサービス・クラス・レベルで@Transactional
アノテーションを指定すると、サービス・エンドポイント・インタフェースで定義された双方向メソッドのすべてに設定が適用されます。フロー・タイプの値はメソッド・レベルでオーバーライドできますが、バージョンはトランザクション全体で一致している必要があります。
@Oneway
アノテーションも追加されているWebメソッドに対して、@Transactional
アノテーションを明示的に指定することはできません。
Webサービス原子性トランザクションは、クライアント側の非同期プログラミング・モデルでは使用できません。
@Transactional
アノテーションを指定する際の形式は次のとおりです。
@Transactional( version=Transactional.Version.[WSAT10|WSAT11|WSAT12|DEFAULT], value=Transactional.TransactionFowType.[MANDATORY|SUPPORTS|NEVER] )
バージョンおよびフロー・タイプの構成オプションの詳細は、表15-2を参照してください。
次の項では、@Transactional
アノテーションをWebサービスの実装クラス・レベルと実装メソッド・レベルで使用する例、およびEJB @TransactionAttributeアノテーションとともに使用する例を示します。
次の例は、@Transactional
アノテーションをWebサービス・クラスに追加する方法を示しています。関連するコードは太字で示されています。例に示すように、アクティブなJTAトランザクションがあります。
注意:
次のコードは、WebLogic Serverサンプル・サーバー付属のWebサービス原子性トランザクションの例から抜粋したものです。詳細は、「Webサービス原子性トランザクションのその他の使用例」を参照してください。
package examples.webservices.jaxws.wsat.simple.service; . . . import weblogic.jws.Policy; import javax.transaction.UserTransaction; . . . import javax.jws.WebService; import weblogic.wsee.wstx.wsat.Transactional; import weblogic.wsee.wstx.wsat.Transactional.Version; import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType; /** * This JWS file forms the basis of a WebLogic WS-Atomic Transaction Web Service with the * operations: createAccount, deleteAccount, transferMonet, listAccount * */ @WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/", portName = "WSHttpBindingIService") @Transactional(value=Transactional.TransactionFlowType.MANDATORY, version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10) public class WsatBankTransferService { public String createAccount(String acctNo, String amount) throws java.lang.Exception{ Context ctx = null; UserTransaction tx = null; try { ctx = new InitialContext(); tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction"); try { DataSource dataSource = (DataSource)ctx.lookup("examples-demoXA-2"); String sql = "insert into wsat_acct_remote (acctno, amount) values (" + acctNo + ", " + amount + ")"; int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate(); if (insCount != 1) throw new java.lang.Exception("insert fail at remote."); return ":acctno=" + acctNo + " amount=" + amount + " creating. "; } catch (SQLException e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new SQLException("SQL Exception during createAccount() at remote."); } } catch (java.lang.Exception e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new java.lang.Exception(e); } } public String deleteAccount(String acctNo) throws java.lang.Exception{ ... } public String transferMoney(String acctNo, String amount, String direction) throws java.lang.Exception{ ... } public String listAccount() throws java.lang.Exception{ ... } }
package jaxws.interop.rsp; ... import javax.jws.WebService; import javax.xml.ws.BindingType; import weblogic.wsee.wstx.wsat.Transactional; import weblogic.wsee.wstx.wsat.Transactional.TransactionalFlowType; import weblogic.wsee.wstx.wsat.Transactional.Version; ... @WebService( portName = "FlightServiceBindings_Basic", serviceName = "FlightService", targetNamespace = "http://wsinterop.org/samples", wsdlLocation = "/wsdls/FlightService.wsdl", endpointInterface = "jaxws.interop.rsp.IFlightService" ) @BindingType("http://schemas.xmlsoap.org/wsdl/soap/http") @javax.xml.ws.soap.Addressing @Transactional(value = Transactional.TransactionFlowType.SUPPORTS, version = Transactional.Version.WSAT12) public class FlightServiceImpl implements IFlightService { ... }
次の例は、@Transactional
アノテーションをWebサービス実装メソッドに追加する方法を示しています。関連するコードは太字で示されています。
package jaxws.interop.rsp; ... import javax.jws.WebService; import javax.xml.ws.BindingType; import weblogic.wsee.wstx.wsat.Transactional; import weblogic.wsee.wstx.wsat.Transactional.TransactionalFlowType; import weblogic.wsee.wstx.wsat.Transactional.Version; ... @WebService( portName = "FlightServiceBindings_Basic", serviceName = "FlightService", targetNamespace = "http://wsinterop.org/samples", wsdlLocation = "/wsdls/FlightService.wsdl", endpointInterface = "jaxws.interop.rsp.IFlightService" ) @BindingType("http://schemas.xmlsoap.org/wsdl/soap/http") @javax.xml.ws.soap.Addressing public class FlightServiceImpl implements IFlightService { ... @Transactional(value = Transactional.TransactionFlowType.SUPPORTS, version = Transactional.Version.WSAT12) public FlightReservationResponse reserveFlight(FlightReservationRequest request) { //replace with your impl here FlightReserverationEnitity entity = new FlightReserverationEnitity(); entity.setAirlineID(request.getAirlineID()); entity.setFlightNumber(request.getFlightNumber()); entity.setFlightType(request.getFlightType()); boolean successful = saveRequest(entity); FlightReservationResponse response = new FlightReservationResponse(); if (!successful) { response.setConfirmationNumber("OF" + CONF_NUMBER++ + "-" + request.getAirlineID() + String.valueOf(entity.getId())); } else if (request.getFlightNumber() == null || request.getFlightNumber().trim().endsWith("LAS")) { successful = false; response.setConfirmationNumber("OF" + "- No flight available for " + request.getAirlineID()); } else { response.setConfirmationNumber("OF" + CONF_NUMBER++ + "-" + request.getAirlineID() + String.valueOf(entity.getId())); } response.setSuccess(successful); return response; }
package examples.webservices.jaxws.wsat.simple.service; . . . import weblogic.jws.Policy; import javax.transaction.UserTransaction; . . . import javax.jws.WebService; import weblogic.wsee.wstx.wsat.Transactional; import weblogic.wsee.wstx.wsat.Transactional.Version; import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType; /** * This JWS file forms the basis of a WebLogic WS-Atomic Transaction Web Service with the * operations: createAccount, deleteAccount, transferMonet, listAccount * */ @WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/", portName = "WSHttpBindingIService") public class WsatBankTransferService { @Transactional(value=Transactional.TransactionFlowType.MANDATORY, version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10) public String createAccount(String acctNo, String amount) throws java.lang.Exception{ Context ctx = null; UserTransaction tx = null; try { ctx = new InitialContext(); tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction"); try { DataSource dataSource = (DataSource)ctx.lookup("examples-demoXA-2"); String sql = "insert into wsat_acct_remote (acctno, amount) values (" + acctNo + ", " + amount + ")"; int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate(); if (insCount != 1) throw new java.lang.Exception("insert fail at remote."); return ":acctno=" + acctNo + " amount=" + amount + " creating. "; } catch (SQLException e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new SQLException("SQL Exception during createAccount() at remote."); } } catch (java.lang.Exception e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new java.lang.Exception(e); } } public String deleteAccount(String acctNo) throws java.lang.Exception{ ... } public String transferMoney(String acctNo, String amount, String direction) throws java.lang.Exception{ ... } public String listAccount() throws java.lang.Exception{ ... } }
次の例は、@Transactional
アノテーションとEJB @TransactionAttribute
アノテーションを併用する方法を示しています。この場合、フロー・タイプの値に互換性があることが必要です(表15-3を参照)。関連するコードは太字で示されています。
package examples.webservices.jaxws.wsat.simple.service; . . . import weblogic.jws.Policy; import javax.transaction.UserTransaction; . . . import javax.jws.WebService; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import weblogic.wsee.wstx.wsat.Transactional; import weblogic.wsee.wstx.wsat.Transactional.Version; import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType; /** * This JWS file forms the basis of a WebLogic WS-Atomic Transaction Web Service with the * operations: createAccount, deleteAccount, transferMonet, listAccount * */ @WebService(serviceName = "WsatBankTransferService", targetNamespace = "http://tempuri.org/", portName = "WSHttpBindingIService") @Transactional(value=Transactional.TransactionFlowType.MANDATORY, version=weblogic.wsee.wstx.wsat.Transactional.Version.WSAT10) @TransactionAttribute(TransactionAttributeType.REQUIRED public class WsatBankTransferService { . . . }
Webサービス原子性トランザクションは、有効にすると、ポリシー・アサーションを使用してWSDLファイルで通知されます。
表15-4は、Webサービス原子性トランザクションのフロー・タイプとEJBトランザクション属性との一般的な組合せに対応するWS-AtomicTransaction 1.2ポリシー・アサーションをまとめたものです。他のすべての組合せではビルド時にエラーが発生します。
表15-4 Webサービス原子性トランザクションのポリシー・アサーションの値(WS-AtomicTransaction 1.2)
原子性トランザクションのフロー・タイプ | EJB @TransactionAttribute | WS-AtomicTransaction 1.2ポリシー・アサーション |
---|---|---|
|
|
|
|
|
|
|
|
ポリシーの通知なし |
wsdlc
Antタスクを使用すると、既存のWSDLファイルから一連のアーティファクトを生成し、それをまとめて、WSDLファイルに記述されたWebサービスの部分的なJava実装を提供することができます。WSDLファイルで通知されたWS-AtomicTransactionポリシー・アサーションは、wsdlc
によって生成された新しいWebサービスのWSDLファイルに送られ、その中に組み込まれます。
wsdlc
Antタスクでは、生成されたJWSインタフェースの部分的な(途中まで作成済の)実装を含むJWSファイルが生成されます。このファイルを変更してビジネス・コードを組み込む必要があります。ビジネス・ロジックを含むJWSファイルをコーディングしたら、jwsc
Antタスクを実行して、Webサービスの完全なJava実装を生成します。wsdlc
Antタスクによって生成されたJARファイル(JWSインタフェース・ファイルとデータ・バインディング・アーティファクトを含む)を指定するには、jwsc
のcompiledWsdl
属性を使用します。この属性を指定した場合、jwsc
Antタスクでは新しいWSDLファイルが生成されるかわりに、JARファイル内のWSDLファイルが使用されます。そのため、WebサービスをデプロイしてそのWSDLを参照すると、デプロイ済のWSDLは開始当初のWSDLとまったく同じように見えます(WS-AtomicTransactionポリシー・アサーションが付いています)。
wsdlc
を使用した、WSDLファイルからのWebサービスの生成の詳細は、「WSDLファイルから開始するWebLogic Webサービスの開発: 主な手順」を参照してください
Webサービス・クライアントに対しては、次のいずれかの方法でWebサービス原子性トランザクションを有効にします。
クライアントのWebサービス参照インジェクション・ポイントに@weblogic.wsee.wstx.wsat.Transactional
アノテーションを追加します。詳細は、「@Transactionalアノテーションと@WebServiceRefアノテーションの併用」を参照してください。
Webサービスのプロキシまたはディスパッチの作成時にweblogic.wsee.wstx.wsat.TransactionalFeature
のインスタンスをパラメータとして渡します。詳細は、「TransactionalFeatureをクライアントに渡す」を参照してください。
デプロイメント時に、WebLogic Server管理コンソールを使用して、Webサービス・クライアントのエンドポイント・レベルまたはメソッド・レベルでWebサービス原子性トランザクションを有効にして構成します。詳細は、「管理コンソールを使用したWebサービス原子性トランザクションの構成」を参照してください。
実行時に、原子性トランザクションに対応していないWebサービス・クライアントが。原子性トランザクションに対応しているWebサービスを呼び出すと、WSDLで示されるフロー・タイプの設定に基づいて次の処理が行われます。
サービス側でフロー・タイプがSUPPORTS
またはNEVER
に設定されている場合、呼出しはトランザクションの一部として組み込まれます。
フロー・タイプがMANDATORY
に設定されている場合、例外がスローされます。
注意:
Webサービス原子性トランザクションは、Java SEクライアントではサポートされていません。
Webサービス原子性トランザクションを有効にする際に設定可能な構成オプションについては、表15-2を参照してください。
Webサービス原子性トランザクションを有効にするには、Webサービス・クライアントのWebサービス参照(@WebServiceRef
)インジェクション・ポイントに@weblogic.wsee.wstx.wsat.Transactional
アノテーションを指定します。
@Transactional
アノテーションを指定する際の形式は次のとおりです。
@Transactional( version=Transactional.Version.[WSAT10|WSAT11|WSAT12|DEFAULT], value=Transactional.TransactionFlowType.[MANDATORY|SUPPORTS|NEVER] )
バージョンおよびフロー・タイプの構成オプションの詳細は、表15-2を参照してください。
次の例は、Webサービス参照インジェクション・ポイントにアノテーションを追加する方法を示しています。関連するコードは太字で示されています。例に示すように、アクティブなJTAトランザクションは原子性トランザクションの一部になります。
注意:
次のコードは、WebLogic Serverサンプル・サーバー付属のWebサービス原子性トランザクションの例から抜粋したものです。詳細は、「Webサービス原子性トランザクションのその他の使用例」を参照してください。
package examples.webservices.jaxws.wsat.simple.client; . . . import javax.servlet.*; import javax.servlet.http.*; . . . import java.net.URL; import javax.xml.namespace.QName; import javax.transaction.UserTransaction; import javax.transaction.SystemException; import javax.xml.ws.WebServiceRef; import weblogic.wsee.wstx.wsat.Transactional; */ /** * This example demonstrates using a WS-Atomic Transaction to create or delete an account, * or transfer money via web service as a single atomic transaction. */ public class WsatBankTransferServlet extends HttpServlet { . . . String url = "http://localhost:7001"; URL wsdlURL = new URL(url + "/WsatBankTransferService/WsatBankTransferService"); . . . DataSource ds = null; UserTransaction utx = null; try { ctx = new InitialContext(); utx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction"); utx.setTransactionTimeout(900); } catch (java.lang.Exception e) { e.printStackTrace(); } WsatBankTransferService port = getWebService(wsdlURL); try { utx.begin(); if (remoteAccountNo.length() > 0) { if (action.equals("create")) { result = port.createAccount(remoteAccountNo, amount); } else if (action.equals("delete")) { result = port.deleteAccount(remoteAccountNo); } else if (action.equals("transfer")) { result = port.transferMoney(remoteAccountNo, amount, direction); } } utx.commit(); result = "The transaction is committed " + result; } catch (java.lang.Exception e) { try { e.printStackTrace(); utx.rollback(); result = "The transaction is rolled back. " + e.getMessage(); } catch(java.lang.Exception ex) { e.printStackTrace(); result = "Exception is caught. Check stack trace."; } } request.setAttribute("result", result); . . . @Transactional(value = Transactional.TransactionFlowType.MANDATORY, version = Transactional.Version.WSAT10) @WebServiceRef(wsdlLocation = "http://localhost:7001/WsatBankTransferService/WsatBankTransferService?WSDL", value = examples.webservices.jaxws.wsat.simple.service.WsatBankTransferService.class) WsatBankTransferService_Service service; private WsatBankTransferService getWebService() { return service.getWSHttpBindingIService(); } public String createAccount(String acctNo, String amount) throws java.lang.Exception{ Context ctx = null; UserTransaction tx = null; try { ctx = new InitialContext(); tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction"); try { DataSource dataSource = (DataSource)ctx.lookup("examples-dataSource-demoXAPool"); String sql = "insert into wsat_acct_local (acctno, amount) values ( " + acctNo + ", " + amount + ")"; int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate(); if (insCount != 1) throw new java.lang.Exception("insert fail at local."); return ":acctno=" + acctNo + " amount=" + amount + " creating.. "; } catch (SQLException e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new SQLException("SQL Exception during createAccount() at local."); } } catch (java.lang.Exception e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new java.lang.Exception(e); } } public String deleteAccount(String acctNo) throws java.lang.Exception{ . . . } public String transferMoney(String acctNo, String amount, String direction) throws java.lang.Exception{ . . . } public String listAccount() throws java.lang.Exception{ . . . } }
package examples.webservices.service_to_service; import javax.jws.WebService; import javax.jws.WebMethod; import javax.xml.ws.WebServiceRef; import weblogic.wsee.wstx.wsat.Transactional; import weblogic.wsee.wstx.wsat.Transactional.TransactionalFlowType; import weblogic.wsee.wstx.wsat.Transactional.Version; import examples.webservices.complex.ComplexPortType; import examples.webservices.complex.ComplexService; ... @WebService(name="ClientPortType", serviceName="ClientService", targetNamespace="http://examples.org") public class ClientServiceImpl { @Transactional(value = Transactional.TransactionFlowType.SUPPORTS, version = Transactional.Version.WSAT12) @WebServiceRef() ComplexService service; @WebMethod() public String callComplexService(BasicStruct input) { // Create service and port stubs to invoke ComplexService ComplexPortType port = service.getComplexPortTypePort(); // Include your implementation here. } }
Webサービスのクライアントに対してWebサービス原子性トランザクションを有効にするには、次の例のように、Webサービスのプロキシまたはディスパッチの作成時にweblogic.wsee.wstx.wsat.TransactionalFeature
のインスタンスをパラメータとして渡します。関連するコードは太字で示されています。
注意:
次のコードは、WebLogic Serverサンプル・サーバー付属のWebサービス原子性トランザクションの例から抜粋したものです。詳細は、「Webサービス原子性トランザクションのその他の使用例」を参照してください。
package examples.webservices.jaxws.wsat.simple.client; . . . import javax.servlet.*; import javax.servlet.http.*; . . . import java.net.URL; import javax.xml.namespace.QName; import javax.transaction.UserTransaction; import javax.transaction.SystemException; import weblogic.wsee.wstx.wsat.TransactionalFeature; import weblogic.wsee.wstx.wsat.Transactional.Version; import weblogic.wsee.wstx.wsat.Transactional.TransactionFlowType; */ /** * This example demonstrates using a WS-Atomic Transaction to create or delete an account, * or transfer money via web service as a single atomic transaction. */ public class WsatBankTransferServlet extends HttpServlet { . . . String url = "http://localhost:7001"; URL wsdlURL = new URL(url + "/WsatBankTransferService/WsatBankTransferService"); . . . DataSource ds = null; UserTransaction utx = null; try { ctx = new InitialContext(); utx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction"); utx.setTransactionTimeout(900); } catch (java.lang.Exception e) { e.printStackTrace(); } WsatBankTransferService port = getWebService(wsdlURL); try { utx.begin(); if (remoteAccountNo.length() > 0) { if (action.equals("create")) { result = port.createAccount(remoteAccountNo, amount); } else if (action.equals("delete")) { result = port.deleteAccount(remoteAccountNo); } else if (action.equals("transfer")) { result = port.transferMoney(remoteAccountNo, amount, direction); } } utx.commit(); result = "The transaction is committed " + result; } catch (java.lang.Exception e) { try { e.printStackTrace(); utx.rollback(); result = "The transaction is rolled back. " + e.getMessage(); } catch(java.lang.Exception ex) { e.printStackTrace(); result = "Exception is caught. Check stack trace."; } } request.setAttribute("result", result); . . . // Passing the TransactionalFeature to the Client private WsatBankTransferService getWebService(URL wsdlURL) { TransactionalFeature feature = new TransactionalFeature(); feature.setFlowType(TransactionFlowType.MANDATORY); feature.setVersion(Version.WSAT10); WsatBankTransferService_Service service = new WsatBankTransferService_Service(wsdlURL, new QName("http://tempuri.org/", "WsatBankTransferService")); return service.getWSHttpBindingIService(new javax.xml.ws.soap.AddressingFeature(), feature); } public String createAccount(String acctNo, String amount) throws java.lang.Exception{ Context ctx = null; UserTransaction tx = null; try { ctx = new InitialContext(); tx = (UserTransaction)ctx.lookup("javax.transaction.UserTransaction"); try { DataSource dataSource = (DataSource)ctx.lookup("examples-dataSource-demoXAPool"); String sql = "insert into wsat_acct_local (acctno, amount) values ( " + acctNo + ", " + amount + ")"; int insCount = dataSource.getConnection().prepareStatement(sql).executeUpdate(); if (insCount != 1) throw new java.lang.Exception("insert fail at local."); return ":acctno=" + acctNo + " amount=" + amount + " creating.. "; } catch (SQLException e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new SQLException("SQL Exception during createAccount() at local."); } } catch (java.lang.Exception e) { System.out.println("**** Exception caught *****"); e.printStackTrace(); throw new java.lang.Exception(e); } } public String deleteAccount(String acctNo) throws java.lang.Exception{ . . . } public String transferMoney(String acctNo, String amount, String direction) throws java.lang.Exception{ . . . } public String listAccount() throws java.lang.Exception{ . . . } }
package jaxws.interop.rsp; ... import javax.jws.WebService; import javax.xml.ws.*; import weblogic.wsee.wstx.wsat.TransactionalFeature; ... @WebService( portName = "TravelAgencyServiceBindings_Basic", serviceName = "TravelAgencyService", targetNamespace ="http://wsinterop.org/samples", wsdlLocation = "/wsdls/TravelAgencyService.wsdl", endpointInterface = "jaxws.interop.rsp.ITravelAgencyService" ) @BindingType("http://schemas.xmlsoap.org/wsdl/soap/http") @javax.xml.ws.soap.Addressing() public class TravelAgencyServiceImpl implements ITravelAgencyService { ... private IFlightService getFlightProxy(String endpoint, String stsEndpoint) throws Exception { TransactionalFeature feature = new TransactionalFeature(); // Optional setting. feature.setVersion(Transactional.Version.WSAT12); // Optional setting. feature.setEnabled("ReserveFlight", true); IFlightService flightProxy = flightService.getFlightServiceBindingsBasic(feature); ... } }
次の項では、WebLogic Server管理コンソールを使用してWebサービス原子性トランザクションを構成する方法について説明します。
トランスポート・レベルのセキュリティを使用して、Webサービス原子性トランザクションのコーディネータと参加者の間で交換されるメッセージを保護するには、WebLogic Server管理コンソールで、次の表に定義されているプロパティを構成します。これらのプロパティは、ドメイン・レベルで構成します。詳細な手順は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのWebサービス原子性トランザクションの構成を参照してください。
表15-5 Webサービス原子性トランザクションの保護
プロパティ | 説明 |
---|---|
Webサービス・トランザクションのトランスポート・セキュリティ・モード |
コーディネータと参加者の間のメッセージ交換に双方向SSLを使用するかどうかを指定します。このプロパティは、次のいずれかの値に設定できます。
詳細は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプの双方向SSLの構成に関する説明を参照してください。 |
Webサービス・トランザクションの発行済みトークンを有効化 |
発行済トークンを使用してコーディネータと参加者の間の認証を有効にするかどうかを指定するフラグ。
|
Webサービス原子性トランザクションを有効にしてバージョンとフロー・タイプを構成する場合、Webサービスまたはクライアントのエンドポイント・レベルまたはメソッド・レベルで構成をカスタマイズできます。詳細な手順は、Oracle WebLogic Server管理コンソール・オンライン・ヘルプのWebサービス原子性トランザクションの構成を参照してください。
原子性トランザクションに対応しているWebサービスをクラスタ環境で使用する際の考慮事項については、クラスタ内のWebサービスの管理を参照してください。
Webサービス原子性トランザクションのその他の使用例については、次の項を参照してください。
Webサービス原子性トランザクションで交換されるメッセージ・ヘッダーの署名と暗号化の方法を示す例は、Oracle WebLogic Server WebLogic Webサービスの保護のWebサービス原子性トランザクションの保護を参照してください。
注意:
Webサービス原子性トランザクションが有効なアプリケーションを保護するために使用できるのは、WebLogic Webサービスのセキュリティ・ポリシーのみです。Oracle Web Services Manager (WSM)ポリシーを使用して保護することはできません。
Webサービス原子性トランザクションの詳しい例がWebLogic Serverサンプル・アプリケーションの一部として提供されています。サンプル・アプリケーションの実行と例へのアクセスの詳細は、Oracle WebLogic Serverの理解のサンプル・アプリケーションおよびサンプル・コードを参照してください。