![]() ![]() ![]() ![]() ![]() ![]() ![]() |
この章では、CORBAサーバー・アプリケーションにトランザクションを統合する方法について、Transactions Universityサンプル・アプリケーションを例にして説明します。Transactionsサンプル・アプリケーションは、学生がコースのセットを登録するプロセスをカプセル化します。Transactionsサンプル・アプリケーションでは、CORBAサーバー・アプリケーションをトランザクションに統合するためのすべての方法ではなく、トランザクションの振る舞いの2つのモデルを示すことによって、アプリケーション一般、特にオブジェクトの永続状態に対するトランザクションの振る舞いの影響を示します。
この章では、また、ユーザー定義の例外に関するセクションを提供します。Transactionsサンプル・アプリケーションはユーザー定義例外を利用します。この例外は、クライアント・アプリケーションに返すことができ、クライアントが開始したトランザクションのロールバックを発生させることが可能です。
Oracle Tuxedoシステムでは、データベースのトランザクションが正確に完了すること、およびデータベースのトランザクションがパフォーマンスの高いトランザクションのACID プロパティ(原子性、一貫性、独立性、および持続性)のすべてを備えることを保証する手段として、トランザクションが提供されています。つまり、永続ストレージに複数の書込み操作を実行する上での要件があるので、操作の成功が保証されている必要があります。操作が1つでも失敗すれば、一連の操作の全体がロールバックされます。
一般に、トランザクションは次のリストで説明される状況に適しています。それぞれの状況は、Oracle Tuxedoシステムでサポートされているトランザクション・モデルをカプセル化しています。
たとえば、旅行代理店アプリケーションがあるとします。クライアント・アプリケーションは、たとえばフランスのストラスブールからオーストラリアのアリス・スプリングスまでなど、遠隔地への旅行を手配する必要があります。このような旅行では、複数の予約が必要になります。クライアント・アプリケーションでは、旅程の各区分の予約が順番に行われます。たとえば、ストラスブールからパリ、パリからニューヨーク、ニューヨークからロサンゼルスの予約が順番に行われます。しかし、いずれかのフライトが予約できないとき、クライアント・アプリケーションにはその時点で予約済のほかのフライトをすべてキャンセルする方法が必要です。たとえば、クライアント・アプリケーションでロサンゼルスからホノルルへの指定日のフライトを予約できなかったら、クライアント・アプリケーションはその時点までに済ませたフライト予約をキャンセルする必要があります。
たとえば、インターネット・ベースのオンライン・ショッピング・アプリケーションを検討してみます。クライアント・アプリケーションのユーザーがオンライン・カタログを一覧して、複数の購入を選択します。ユーザーは、購入したい商品をすべて選択したら、ボタンをクリックして購入を実行し、クレジット・カード情報を入力します。クレジット・カードの確認が失敗したら(たとえば、ユーザーのクレジット・カード情報が無効だった場合)、ショッピング・アプリケーションでは、未決済の購入選択をすべて取り消したり、会話で行われたすべての購入トランザクションをロールバックしたりできる必要があります。
たとえば、銀行取引アプリケーションがあるとします。クライアントは、窓口オブジェクトに対して振替オペレーションを呼び出します。振替オペレーションは、銀行データベースに対して以下の呼出しを実行するために窓口オブジェクトを必要とします。
ここでは、CORBAサーバー・アプリケーションでのトランザクションを設計および実装する方法について、Transactions Universityサンプル・アプリケーションを例にして説明します。また、ここでは、Transactionsサンプル・アプリケーションの動作と、トランザクションを実装する際の設計上の考慮事項についても説明します。トランザクション全般の詳細は、「トランザクションのCORBAクライアントおよびサーバー・アプリケーションへの統合」を参照してください。
Transactionsサンプル・アプリケーションは、学生がコースのセットを登録するプロセスを、トランザクションを利用してカプセル化します。このアプリケーションで使用されているトランザクション・モデルは、前の項で説明したように、会話モデルと、単一の呼出しがデータベースに対して複数の操作を個別に行うモデルを組み合せたものです。
このTransactionsサンプル・アプリケーションは、Securityサンプル・アプリケーションを基に以下の機能を追加したものです。
Transactionsサンプル・アプリケーションは、次の2とおりの方法でトランザクションをロールバックします。
したがって、Transactionsサンプル・アプリケーションでも、ユーザー定義のCORBA例外を実装する方法が示されています。たとえば、学生が登録可能なコースの最大数を超えているコースに登録しようとすると、サーバー・アプリケーションは、TooManyCredits
例外を戻します。クライアント・アプリケーションは、この例外を受け取ると、トランザクションを自動的にロールバックします。
学生を登録するプロセスを実装するために、Transactionsサンプル・アプリケーションは、以下の作業を実行します。
Registrar
オブジェクトのregister_for_courses()
操作は、登録のリクエストを処理するためにループを実行し、リストの各コースについて次の処理を繰り返します。register_for_courses()
操作は、クライアント・アプリケーションにパラメータNotRegisteredList
を戻します(このパラメータには、登録に失敗したコースのリストが含まれています)。 NotRegisteredList
の値が空の場合、クライアント・アプリケーションはトランザクションをコミットします。
NotRegisteredList
値にコースが含まれていない場合、クライアント・アプリケーションは、登録に成功したコースに対する登録プロセスを完了するかどうかを指定するよう学生に要求します。登録を完了するように選択した場合、クライアント・アプリケーションはトランザクションをコミットします。登録を取り消すように選択した場合、クライアント・アプリケーションはトランザクションをロールバックします。
Registrar
オブジェクトはTooManyCredits
例外をクライアント・アプリケーションに返し、クライアント・アプリケーションはトランザクションの全体をロールバックします。 Transactionsサンプル・アプリケーションの基本設計原理は、コース登録を一度に1つではなくグループ単位で処理することです。この設計原理によって、Registrar
オブジェクトに対するリモート呼出しの数を最小化できます。
この設計の実装で、Transactionsサンプル・アプリケーションは、「Oracle Tuxedoシステムでのトランザクションの概要」で説明しているトランザクションの使用の1モデルを示します。このモデルの特徴は、次のとおりです。
begin()
操作を呼び出してトランザクションを開始し、次にRegistrar
オブジェクト上でregister_for_courses()
操作を呼び出します。 Registrar
オブジェクトは、登録可能なコースについて学生を登録してから、登録のプロセスに失敗したコースのリストを返します。クライアント・アプリケーションは、トランザクションをコミットするかロールバックするかを選択できます。トランザクションは、クライアント・アプリケーションとサーバー・アプリケーションの間の会話をカプセル化します。
register_for_courses()
操作は、Universityデータベースの複数チェックを実行します。いずれか1つのチェックが失敗した場合、トランザクションをロールバックできます。Transactions Universityサンプル・アプリケーションはトランザクションに関与するため、Universityサーバー・アプリケーションは通常、オブジェクト状態に関していくつかの点(特にロールバック時の)を考慮する必要があります。ロールバックが発生した場合、サーバー・アプリケーションは、関連するすべてのオブジェクトが、正しい状態に復元された永続状態を持つことを保証する必要があります。
Registrar
オブジェクトがデータベースのトランザクションに使用されるので、このオブジェクトについてはトランザクションに関与させるのが正しい設計上の選択です。つまり、このオブジェクトのインタフェースにalways
トランザクション・ポリシーを割り当てることです。オブジェクト呼出し時にトランザクションがまだスコープ指定されていない場合、Oracle Tuxedoシステムは、トランザクションを自動的に開始します。
Registrar
オブジェクトを自動的にトランザクション・モードになるようにすることで、このオブジェクトによって実行されるすべてのデータベース書込み操作は、常にトランザクションのスコープ内で行われることになり、クライアント・アプリケーションによってトランザクションが開始されたかどうかは関係がなくなります。サーバー・アプリケーションはXAリソース・マネージャを使用し、またオブジェクトは、データベースに書込みを実行するときにトランザクションにあることが保証されます。したがって、XAリソース・マネージャがオブジェクトの代わりにロールバックまたはコミットの権限を持つことになるので、オブジェクトにはロールバックまたはコミット権限がありません。
しかし、RegistrarFactory
オブジェクトは、トランザクションの過程で使用されるデータを管理しないのでトランザクションから除外してもかまいません。オブジェクトをトランザクションから除外することで、トランザクションに課せられる処理のオーバーヘッドを最小化します。
Registrar
オブジェクトをトランザクションに関与するようにするために、ICFファイルはRegistrar
インタフェースにalways
トランザクション・ポリシーを指定します。したがって、Transactionサンプル・アプリケーションでは、ICFファイルで、Registrar
インタフェースに対して次のオブジェクト・ポリシーを指定します。
RegistrarFactory
オブジェクトをトランザクションから除外するために、ICFファイルはRegistrar
インタフェースにignore
トランザクション・ポリシーを指定します。したがって、Transactionサンプル・アプリケーションでは、ICFファイルで、RegistrarFactory
インタフェースに対して次のオブジェクト・ポリシーを指定します。
Transactionsサンプル・アプリケーションは、オブジェクト状態データを自動的に処理するOracleトランザクション・マネージャ・サーバー(TMS)を使用します。XAリソース・マネージャを使用すると、サーバー・アプリケーションで管理される別のオブジェクトが、データベースとの間のデータの読み書きをどのように実行するかについて、以下のような特定の要件が適用されます。
CourseSynopsisEnumerator
オブジェクトは、データベースからの読取りを行うため、トランザクション内にスコープ指定される必要があります。XAリソース・マネージャの特徴は、ロールバック時のオブジェクト状態データの処理に関する設計の問題をより簡単なものにすることです。トランザクションに関与するオブジェクトは、コミットおよびロールバック権限をXAリソース・マネージャに委任します。これによって、サーバー・アプリケーションの実装は、大幅に単純化されます。
Universityサンプル・アプリケーションは、Oracleのトランザクション・マネージャ・サーバー(TMS)を使用します。Oracleのデータベースを使用するには、サーバー・アプリケーションを構築する際に、Oracleから提供された特定のファイルを含める必要があります。
Transactionsサンプル・アプリケーションの構築、構成および実行の詳細は、CORBA Universityサンプル・アプリケーション・ガイドを参照してください。また、オンライン・ドキュメントにも、各サンプル・アプリケーション用のUBBCONFIG
ファイルと、ファイルの各エントリの説明が示されています。
Oracle Tuxedoシステムは、次のようにしてトランザクションをサポートします。
rollback_only()
操作を呼び出して、トランザクションをロールバックのみとしてマークできます。これによって、現在のトランザクションがコミットされるのを防ぐことができます。エンティティ(通常はデータベース)が破損データまたは不正確なデータで更新される危険がある場合、オブジェクトは、トランザクションをrollbackとしてマークしなければならない場合があります。Tobj_ServantBase::deactivate_object()
操作を呼び出してreason値を渡すことを意味します。) オブジェクトがポーリングされるとき、そのオブジェクトがTransactionCurrentオブジェクトのrollback_only()
操作を呼び出して現在のトランザクションのコミットを拒否する可能性があります。さらに、現在のトランザクションがロールバックされる場合、オブジェクトは、データベースへの書込みをスキップできます。現在のトランザクションのコミットを拒否するオブジェクトがなければ、トランザクションはコミットされます。
以後の節では、必要なトランザクションの振る舞いをオブジェクトに指定するためにオブジェクトのアクティブ化ポリシーとトランザクション・ポリシーを使用する方法を説明します。これらのポリシーは、インタフェースに適用されます。したがって、そのインタフェースを実装しているすべての操作とオブジェクトに適用されます。
注: | サーバー・アプリケーションが、トランザクションに参加するオブジェクトを管理している場合、そのアプリケーションのServerオブジェクトは、TP::open_xa_rm() 操作およびTP::close_xa_rm() 操作を呼び出す必要があります。データベース接続の詳細は、「XAリソース・マネージャのオープン」を参照してください。 |
Oracle Tuxedoシステムは、always
トランザクション・ポリシーを提供します。これは、オブジェクトが呼び出されたときにトランザクションがまだスコープ指定されていない場合、Oracle Tuxedoシステムがトランザクションを自動的に開始するように、そのオブジェクトのインタフェースを定義します。そのオブジェクトの呼出しが完了すると、Oracle Tuxedoシステムは、自動的にトランザクションをコミットまたはロールバックします。サーバー・アプリケーションもオブジェクト実装も、この状態でTransactionCurrentオブジェクトを呼び出す必要はありません。つまり、Oracle Tuxedoシステムは、サーバー・アプリケーションの代わりに自動的にTransactionCurrentオブジェクトを呼び出します。
オブジェクトのインタフェースにalways
トランザクション・ポリシーを割り当てることが適切なのは、次の場合です。
オブジェクトを自動的にトランザクションに関与させる必要がある場合は、当該のオブジェクトのインタフェースに関する次のポリシーを実装構成ファイル(ICFファイル)に記述します。
注: | データベース・カーソルは、複数のトランザクションにまたがることができません。CORBAのUniversityサンプル・アプリケーションにあるCourseSynopsisEnumerator オブジェクトでは、一致するコース概要をUniversityデータベースで検索するためにデータベース・カーソルが使用されています。データベース・カーソルは複数のトランザクションにまたがることができないため、CourseSynopsisEnumerator オブジェクトに対するactivate_object() 操作は一致するすべてのコース概要をメモリーに読み込みます。カーソルはイテレータ・クラスによって管理されているため、CourseSynopsisEnumerator オブジェクトからは見えないことに注意してください。 |
オブジェクトをトランザクションのスコープ内で呼び出すことができるようにする必要がある場合、optional
トランザクション・ポリシーをそのオブジェクトのインタフェースに割り当てることができます。optional
トランザクション・ポリシーは、データベース書込み操作を実行しないものの、トランザクション時に呼び出すことができるようにする必要があるオブジェクトに適しています。
オブジェクトにoptionalトランザクション・ポリシーを適用するために、そのオブジェクトのインタフェース用のICFファイルで次のポリシーを指定できます。
オブジェクトがデータベースのwrite文を実行せず、かつオブジェクトをトランザクションに関与できるようにする場合、always
トランザクション・ポリシーを割り当てる方法が、一般的には最良の選択です。ただし、好みに合せて、optional
ポリシーを使用して、TransactionCurrentオブジェクトでの呼出しでwrite文をカプセル化できます。つまり、オブジェクトがまだトランザクション内にスコープ指定されていない場合、データを書き込む操作内で、トランザクションを開始およびコミットまたはロールバックするためにTransactionCurrentオブジェクトを呼び出し、write文の周囲にトランザクションをスコープします。これによって、データベース書込み操作がトランザクションに関与する形で処理されます。また、パフォーマンスも向上します。このオブジェクトがトランザクションのスコープ内で呼び出されなければ、すべてのデータベース読取り操作が非トランザクション型になるので、効率が高くなります。
注: | Oracle Tuxedoシステムで使用されるXAリソース・マネージャの一部では、トランザクションに関与するすべてのオブジェクトについて、データベース書込み操作に加えて読取り操作についても、トランザクション内でスコープ指定する必要があります。(しかし、それでも独自にトランザクションのスコープ指定はできます。)たとえば、Oracle TuxedoシステムでOracle TMSを使用する場合に、この要件が該当します。トランザクション・ポリシーを選択してオブジェクトに割り当てる場合、使用しているXAリソース・マネージャの要件を把握します。 |
多くの場合、オブジェクトをトランザクションから除外することは危険です。このようなオブジェクトがトランザクション時に呼び出されると、オブジェクトは例外を戻し、トランザクションがロールバックされることがあります。Oracle Tuxedoシステムにはnever
トランザクション・ポリシーが用意されていて、これをオブジェクトのインタフェースに割り当てれば、現在のトランザクションが一時停止中でも、特定のオブジェクトがトランザクションの処理中に呼び出されないようにできます。
このトランザクション・ポリシーは、ロールバックできないディスクに永続状態を書き込むオブジェクトに適しています。たとえば、XAリソース・マネージャに管理されていないディスクにデータを書き込むオブジェクトなどです。クライアント・アプリケーションで、呼出しの一部がトランザクションのスコープ指定を引き起こしているかどうかを認識できない場合、クライアント/サーバー・アプリケーションでこの機能を使用することは重要です。したがって、トランザクションがスコープ指定されている場合、このポリシーを持つオブジェクトが呼び出されると、トランザクションをロールバックできるようになります。
トランザクションがスコープ指定されているときにオブジェクトの呼出しを禁止するには、ICFファイルで当該のオブジェクトのインタフェースに次のポリシーを割り当てます。
トランザクションの過程でオブジェクトの呼出しを許可し、ただしそのオブジェクトをトランザクションの一部にはしないことがふさわしい場合もあります。このようなオブジェクトがトランザクションの最中に呼び出された場合、トランザクションは自動的に一時停止します。オブジェクトに対する呼出しが完了すると、トランザクションは自動的に再開します。この目的のために、Oracle Tuxedoシステムにはignore
トランザクション・ポリシーが用意されています。
ignore
トランザクション・ポリシーは、通常はデータをディスクに書き込まないファクトリなどのオブジェクトに適している場合があります。ファクトリをトランザクションから除外することで、そのファクトリは、トランザクションの最中でもほかのクライアントの呼出しに使用できるようになります。さらに、このポリシーを使用すると、トランザクションに関与しているオブジェクトを呼び出す際のオーバーヘッドが軽減されるので、サーバー・アプリケーションの処理効率が向上します。
トランザクションがオブジェクトに伝播されることを禁止するには、ICFファイルで当該のオブジェクトのインタフェースに次のポリシーを割り当てます。
ICFファイルを作成してオブジェクトにポリシーを指定する方法の詳細は、「ステップ4: メモリー内でのオブジェクトの振る舞いの定義」を参照してください。
オブジェクトのインタフェースにalways
またはoptional
トランザクション・ポリシーが適用されている場合は、ServerオブジェクトのServer::initialize()
操作のTP::open_xa_rm()
操作を呼び出す必要があります。リソース・マネージャは、UBBCONFIG
ファイルのGROUPS
セクションにあるOPENINFO
パラメータで提供された情報を基にオープンされます。デフォルト・バージョンのServer::initialize()
操作は、リソース・マネージャを自動的にオープンします。
データをディスクに書き込まず、トランザクションに参加しているオブジェクト(通常、トランザクション・ポリシーはoptional
)がある場合、TP::open_xa_rm()
操作への呼出しを含める必要があります。その呼出しでは、NULLリソース・マネージャを指定します。
ServerオブジェクトのServer::initialize()
操作が、XAリソース・マネージャをオープンする場合は、Server::release()
操作に次の呼出しを含めます。
TP::close_xa_rm();
CORBAクライアントおよびサーバー・アプリケーションにトランザクションが必要な場合に、トランザクションとオブジェクト状態の管理を統合する方法は複数あります。一般に、Oracle Tuxedoシステムでは、操作呼出しの間のトランザクションについてスコープ指定を自動的に行うようにでき、このときにアプリケーションのロジックを変更したり、オブジェクトが永続状態をディスクに書き込む方法を変更したりする必要はありません。
ここでは、トランザクションとオブジェクト状態の管理に関する重要な項目の一部を説明します。
XAリソース・マネージャを使用すると、たとえばCORBA Universityサンプル・アプリケーションで使用されるOracleのリソース・マネージャなどであれば、一般に、ロールバックでのオブジェクト状態データの処理に関連する設計上の問題が簡単になります。トランザクション・オブジェクトはコミットおよびロールバックの処理をいつでもXAリソース・マネージャに委任できるので、このことによってサーバー・アプリケーションを実装する作業が大幅に簡略化されます。つまり、トランザクションに関与するプロセス・バウンドまたはメソッド・バウンド・オブジェクトは、トランザクション時にデータベースに書込みを実行し、トランザクションのロールバック時にリソース・マネージャに従ってデータベースに書き込まれたデータをロールバックできます。
transaction
アクティブ化ポリシーは、トランザクションの作業が完了するまで書き込まない、または書き込めないメモリー内の状態をディスクに保持するオブジェクトに適しています。transaction
アクティブ化ポリシーをオブジェクトに割り当てると、オブジェクトは、次のようになります。
トランザクションの作業が完了したら、Oracle Tuxedoシステムは各トランザクション・バウンド・オブジェクトのTobj_ServantBase::deactivate_object()
操作を呼び出して、DR_TRANS_COMMITTING
またはDR_TRANS_ABORT
のどちらかのreason
コードを渡します。変数がDR_TRANS_COMMITTING
の場合、オブジェクトは、データベース書込み操作を呼び出すことができます。変数がDR_TRANS_ABORT
であれば、オブジェクトは自身のデータベース書込み操作を省略します。
transaction
アクティブ化ポリシーのオブジェクトへの割当ては、以下のような場合に適しています。
ロールバックの対象となる可能性のあるデータベース書込み操作の数を減らすことができるので、これによって、パフォーマンスがより効率的になります。
Oracle Tuxedoシステムがreason値としてDR_TRANS_COMMITTING
を渡す場合、オブジェクトは、必要であればTransactionCurrentオブジェクトのrollback_only()
操作を呼び出すことができます。Tobj_ServantBase::deactivate_object()
操作の内部でrollback_only()
操作を呼び出した場合、そのTobj_ServantBase::deactivate_object()
操作が再度呼び出される点に注意してください。
トランザクションのコミットを待機してからデータベースに書き込む機能をオブジェクトに付与するには、ICFファイルに当該のオブジェクトのインタフェースに次のポリシーを割り当てます。
注: | トランザクション・バウンド・オブジェクトは、Tobj_ServantBase::deactivate_object() 操作内でトランザクションを開始したり、他のオブジェクトを呼び出したりすることはできません。トランザクション・バウンド・オブジェクトがTobj_ServantBase::deactivate_object() 操作の内部から実行できる有効な呼出しは、データベースへの書込み操作のみです。 |
注: | また、トランザクションに関与するオブジェクトがある場合、そのオブジェクトを管理するServerオブジェクトは、管理されるオブジェクトがディスクにデータを一切書き込まない場合でも、XAリソース・マネージャをオープンするための呼び出し、およびクローズするための呼出しをそれぞれ含んでいる必要があります。(データをディスクに書き込まない、トランザクションに関与するオブジェクトがある場合は、NULLリソース・マネージャを指定します。)XAリソース・マネージャのオープンとクローズの詳細は、「XAリソース・マネージャのオープン」および「XAリソース・マネージャのクローズ」を参照してください。 |
CORBAクライアント/サーバー・アプリケーションにトランザクションを統合する際の注意事項は、以下のとおりです。
CORBA::OBJ_ADAPTER
トランザクション内にあるクライアントが、現在別のトランザクション内にあるオブジェクトに対して操作を呼び出そうとすると、以下のエラー・メッセージが発行されます。
CORBA::INVALID_TRANSACTION
Tobj_ServantBase::deactivate_object()
操作で行うことを検討してください。これにより、Tobj_ServantBase::deactivate_object()
操作が呼び出された時点でトランザクションの結果が分かるため、オブジェクトが自身の状態を適切に扱うことが簡単になります。always
を割り当てたオブジェクトが、クライアント・アプリケーションではなくOracle Tuxedoシステムで開始されたトランザクションに関与している場合は、以下に注意してください。 オブジェクトの操作の内部で例外が発生した場合、クライアント・アプリケーションはOBJ_ADAPTER
例外を受け取ります。この状況で、Oracle Tuxedoシステムは自動的にトランザクションをロールバックします。ただし、クライアント・アプリケーションは、トランザクションがOracle Tuxedoドメインでスコープ指定されていないことをまったく認識していません。
注: | WebLogic Enterpriseバージョン4.2ソフトウェアでは、この状況を回避する方法がありません。トランザクションを開始する前に、アプリケーションができるだけ周到にデータの検証を実行するようにしてください。 |
Transactionsサンプル・アプリケーションには、ユーザー定義例外TooManyCredits
のインスタンスが含まれています。クライアント・アプリケーションが学生をコースに登録しようとしたときに、学生が登録可能なコースの最大数を超えている場合、サーバー・アプリケーションはこの例外をスローします。クライアント・アプリケーションは、この例外を捕捉すると、学生をコースに登録するトランザクションをロールバックします。ここでは、CORBAクライアント/サーバー・アプリケーションでユーザー定義例外を定義および実装する方法について、TooManyCredits
を例にして説明します。
CORBAクライアント/サーバー・アプリケーションにユーザー定義例外を含める作業には、次の手順が関与します。
クライアント/サーバー・アプリケーションのOMG IDLファイルでは、以下の作業を行います。
TooManyCredits
例外は、学生が登録できる単位の最大数を表すshort型の整数値を渡すために定義します。したがって、TooManyCredits
例外の定義には、次のOMG IDL文が含まれます。exception TooManyCredits
{
unsigned short maximum_credits;
};
Registrar
インタフェースのregister_for_courses()
操作に対するOMG IDL文を示したものです。NotRegisteredList register_for_courses(
in StudentId student,
in CourseNumberList courses)
raises (TooManyCredits);
例外を使用する操作の実装では、次の例のように、例外をスローするコードを記述します。
if ( ... ) {
UniversityZ::TooManyCredits e;
e.maximum_credits = 18;
throw e;
}
![]() ![]() ![]() |