1.4.4 トランザクションと排他制御

<この項の構成>
(1) トランザクション制御
(2) 排他制御
(3) 排他エラーとデッドロック

(1) トランザクション制御

DABroker for C++を使ったトランザクション制御には二つの方法があります。一つ目は, DABroker for C++のクラスライブラリを使ってトランザクションを制御する方法であり,一つのDBMSを対象にトランザクション制御ができます。二つ目は,CORBAアプリケーションの場合にTPBrokerのOTS機能を使ってトランザクションを制御する方法であり,複数のDBMSを対象にトランザクション制御ができます。

データベースを更新するアプリケーションでは,DBMSごとに必ずどちらかのトランザクション制御を設定してください。

(a) 一つのDBMSを対象にトランザクション制御を行う方法

簡易版クラスと詳細版クラスでは,トランザクションの制御方法が異なります。簡易版クラスは,Connectメソッドを実行するとそのオブジェクトはトランザクション開始状態になります。詳細版クラスでは,トランザクション制御の有無を選択可能できます。トランザクション制御するには,DBTransactionクラスの,BeginTransメソッド,Commitメソッド,Rollbackメソッドを使用して制御します。

(b) 複数のDBMSを対象にトランザクションの同期制御を行う方法

複数のデータベースに対して更新する場合,障害が発生したときでも複数のデータベース間で矛盾がないよう2相コミットと呼ばれる方法で,複数のDBMSに対して同期を取り,コミット又はロールバックすることが可能です。コミット処理中に障害が発生した場合でも,トランザクション内のすべての変更処理を矛盾なく自動的にロールバックできます。

DABrokerとTPBrokerのOTS機能を組み合わせてこのトランザクション制御を備えたシステムが構築できます。

(2) 排他制御

データベースのテーブルは,複数のアプリケーションからアクセスされます。このような環境で動作するアプリケーションでは,レコードの排他制御を意識したデータベースアクセスを行う必要があります。レコードの排他を意識したアプリケーションを設計しないと,データベースシステム全体の性能が低下するなどの影響が出ます。

排他制御は,データベースの検索・更新方法にもよりますが,基本的にResultsetを使用したデータベースアクセスで意識する必要があります。

DABroker for C++では,下記の排他方法を提供しています。

データベースごとに排他の機能や利用方法が異なるので,上記の方法がすべてのデータベースで利用できるわけではありません。排他制御については,正しく理解して利用することが必要です。

(3) 排他エラーデッドロック

データベースをアクセスするアプリケーションでは,必ず,排他エラーとデッドロックを意識する必要があります。

この排他エラーとデッドロックのエラーコードは,DBMSによって異なりますが,DABrokerでは,このエラーコードの違いを吸収し,アプリケーションでは,DBMSを意識することなくエラー処理を記述できます。

(a) 排他エラーとは

排他エラーとは,アプリケーションがデータベースをアクセスしようとした時に,アクセス対象のレコードが,他のアプリケーションにロックされている状態を意味しています。この状態が発生した時に,待ちとするか,エラー報告するかを選択できる機能を提供しています。

(b) 排他エラー処理形態の設定

排他待ちが発生した時の処理方法を,データベース接続時のConnectメソッドで指定できます。

これ以外に,ロックされていたときのエラースロー時に,ロールバックするかどうかを指定する, LOCK_OPT_WITH_ROLLBACK, LOCK_OPT_WITHOUT_ROLLBACKがありますが,使用するDBMSによって動作が異なるため,詳細については「4.簡易版関数詳細」又は「5.詳細版関数詳細」のConnectメソッドを参照してください。

(c) デッドロックとは

二つ以上のトランザクションが二つ以上の資源の確保をめぐって互いに相手を待つ状態となり,そこから先へ処理が進まなくなることをデッドロックといいます。

デッドロックは,アプリケーションからアクセスするテーブルやレコードの処理する順番が統一されていない場合やロック範囲が広い場合など,さまざまなケースで発生します。

デッドロック状態となることを防ぐ目的で,DBMSは,一つのアプリケーションにデッドロックを通知します。このデッドロック状態を通知されたアプリケーションは,すみやかにロールバックし,ロックしているレコードを解放する必要があります。

データベースアクセス中にデッドロックが発生するとエラーがスローされ,DBSQLCAクラスのe_USERCODEに20002,e_USERERRORにエラーメッセージが設定されます。