Webサービスによる企業間システム連携を実用に移すために必要となると言われている技術要素の一つに、トランザクション管理があります。トランザクション管理は複数の処理を矛盾無く確実に行うために不可欠なもので、高い信頼性が求められる企業間取引などでも必要となります。
Webサービスによる企業間システム連携を実用に移すために必要となると言われている技術要素の一つに、トランザクション管理があります。トランザクション管理は複数の処理を矛盾無く確実に行うために不可欠なもので、高い信頼性が求められる企業間取引などでも必要となります。
本稿では、Webサービスで利用可能なトランザクションのための仕様として、現在OASISで策定が行われているBusiness Transaction Protocol(以下BTP)の概要について述べます。BTPは、企業間にまたがったトランザクション管理を行う場合に、トランザクションに参加するシステムや管理機構が従うべき通信や動作を定めたもので、Webサービスを利用するシステムがこの仕様をサポートすることで企業間取引などでもトランザクション処理を利用することが可能となります。
なお、本稿執筆時点の仕様のバージョンは0.9.5であり、今後仕様が変更になる可能性がある事を予めお断りしておきます。BTPの仕様書ならびに解説はOASISのホームページ(http://www.oasis-open.org/committees/business-transactions/)からダウンロードできます。
トランザクションとは、コンピュータによるデータ処理を、ハードウェアやソフトウェアの障害などが発生しても全体に破綻をきたさないよう処理を確実に行うために、古くから用いられている技術です。
例えば簡単な例として、銀行のある口座から別の口座にお金を移す処理を考えてみます。これは最初の口座からお金を下ろすという処理と、次の口座にお金を振り込むという2つの処理からなります。ここで、もし最初のお金を下ろす処理と次のお金を振り込む処理の間にシステムが障害でダウンしてしまった時に、最初の口座からはお金が引き落とされているのに次の口座にはお金が振り込まれていなかったら、データの上ではお金が消えてしまうことになります。これでは安心してシステムを利用することが出来ません。このような問題が発生しないよう、この2つの処理を必ず一緒に行い、口座のデータは必ず2つの処理の両方が実行前か実行後のいずれかの状態であり、処理の途中と言う矛盾のある状態を作らない事を保証するのが、トランザクション処理です。
一般的なトランザクション処理を行うシステムの構成は図1のようになります。アプリケーションはデータを操作する命令を発行します。データベースは実際のデータを格納していて、アプリケーションからの命令に従ってデータを変更します。トランザクションマネージャは両者の間に立って、トランザクションの性質を実現するよう両者の調整を行います。銀行口座の例なら、アプリケーションはまずトランザクションマネージャにトランザクションの開始を指示し、それからデータベースに対してお金の引き落としとお金の振込という2つのデータの書換えの指示を行い、最後にトランザクションマネージャにトランザクションの終了を指示します。一方データベースはデータの書換えの指示がくると、トランザクションマネージャに自身を登録してから、2つのデータの書換えを仮に実行します。そして、その後トランザクションマネージャから仮実行結果を本物の結果として確定して良いという指示(コミットと言います)がくると、その時点で始めて口座のデータを本当に、二つ合わせて書換えます。一方もしトランザクションマネージャがコミットを指示する前にシステムが障害で停止してしまったり、アプリケーションが途中で処理の中断を指示した場合、仮実行の結果は破棄され(ロールバックと言います)、データベースはどちらの口座のデータも変更していない状態に維持されます。
Webサービスによる企業間システム連携でも、同じような機能が必要になります。
例えば、航空券、レンタカー、ホテルの予約を必要とする旅行予約を行うシステムを考えてみます。予約は、航空会社、レンタカー会社、ホテルのそれぞれの独立したシステムでWebサービスとして提供されており、旅行予約システムはこれらのWebサービスを呼び出して旅行予約処理を行います(図2)。
旅行としてはこの3つ全てが揃わないと成立しませんので、途中どれか一つでも予約に失敗したら他の予約も全て取り消されなければなりません。言い換えれば、旅行予約システムはこの3つの予約を一つのトランザクションで処理しなければなならいと言う事です。このような、企業間、システム間にまたがったトランザクションをビジネストランザクションと呼びます。この場合、旅行予約システムがトランザクションを制御する側、航空会社、レンタカー会社、ホテルの予約システムがトランザクションに参加する側になります。
そして、このビジネストランザクションを実現するために、各企業の各システムが守らなければならない決まり事を定めたのが、ビジネストランザクションプロトコル(BTP)です。
このビジネストランザクションの基本的な考え方は、一般的なトランザクションと大きく異なるものではありません。しかし、企業間のシステム連携では、従来のトランザクションが想定している単一あるいはLANなどで密結合されたシステム内部での利用とは幾つか前提が異なります。
一つは、システム同士が非常に粗に結合されており、個々のシステムの独立性が高いという点です。従来のトランザクションを使用する環境では、トランザクションに参加するデータベースなどは基本的に一つのシステム内の機能部品にすぎませんが、ビジネストランザクションの場合、トランザクションの個々の参加者は異なる企業や部門に属するシステムであり、それぞれ異なるポリシーで設計、構築、運用されます。このため、参加者は全てが同一のアーキテクチャを採用し中央の管理機構に完全に従うのではなく、様々なアーキテクチャで、より自律的に動作できたり、あるいは動作してしまった場合へ対処できる事が求められます。
もう一つは、トランザクション処理が長時間に及ぶ可能性がある、という点です。従来のトランザクションではトランザクションが開始されてから終了するまでせいぜい数秒、長くても数十秒程度であることを仮定していますが、ビジネストランザクションの場合、トランザクションにかかる時間は数時間や数日といった場合も考えられます。
このような違いのため、ビジネストランザクションを実現するのに、従来のトランザクションの機構や性質をそのまま導入するのは色々と不都合が生じます。そこでBTPでは、従来のトランザクションの制約を若干弱め、従来のトランザクションの枠組をこのような粗結合、長時間処理に適応できるよう拡張しています。
次に、BTP を使用したシステムの動作例を例に、BTP によるトランザクション管理のイメージを説明します。
図3は、ビジネストランザクションを行う簡単なシステムでの、基本的なシステムの構成要素を図示したものです。図の右側が Webサービスを提供するシステム側(例:航空会社、レンタカー会社、ホテルのシステム)、左側がWebサービスを利用する側(例:旅行予約システム)になります。また、図の上部はシステムのうちアプリケーションの部分、下部はBTPを実現する管理処理の部分です。図の簡単化のためにサービス提供側は一つにしていますが、通常はサービスは複数になります。
アプリケーション側の要素は、通常のWebサービスと同じくサービスとクライアントからなります。クライアントはサービスに要求、例えばチケット予約要求を送り、結果をもらいます。サービスは受け取った要求に従い、何らかの処理、例えばチケット予約処理を行います。一方、BTP処理の要素は、クライアント側にCoordinator、サービス側に Participant という要素が用意されます。Coordinator と Participant は従来のトランザクションのトランザクションマネージャに相当する部分で、Coordinator はクライアント側、Participant はサービス側でそれぞれトランザクション制御のための処理を行います。
クライアントがビジネストランザクションを用いてサービスを利用する時の動作は以下のようになります。
もし7.でクライアントがトランザクションを取り消す事を選択した場合、代わりに CANCEL_TRANSACTION メッセージを Coordinator に送り、トランザクションの取り消しを指示します。あるいは Participant が何らかの理由によって処理を確定出来なくなった場合、8. でPREPARED の代わりに CANCELLED メッセージを返します。いずれの場合も、Coordinator はトランザクション全体の確定が不可能と判断してトランザクションの取り消しを決定し、全てのParticipant に CANCEL メッセージを送ります。CANCEL メッセージを受信した Participant はサービスに働きかけ、サービスの仮実行の結果を取り消させます。この結果、トランザクションに関連した処理は全て取り消され、「何も実行されなかった事」として扱われます。
このようにして、BTP ではシステム間で通常のアプリケーションのメッセージに加えてトランザクション管理のためのメッセージをやりとりして、ビジネストランザクションを実現します。
先の説明では、サービスやParticipantで「処理の仮実行」「処理結果の確定」「処理結果の取り消し」などを行うと述べました。これは、最初に処理を実行する時にはあくまで仮実行としておいて、後で確定や取り消しの指示が来た時に、実際に結果を確定させたり、あるいは処理の結果を無かった事として取り消す、という動作です。これはビジネストランザクションを実現する上で非常に重要な動作ですが、では、サービスやParticipantを実装するシステムは、どのようにしてこのような動作を実現するのでしょうか?
実はBTPではこの動作の実現方法については何も規定しておらず、実現方法はサービス側のアプリケーションやBTP処理のシステムの実装者に完全に任されています。BTP の仕様が要求しているのはビジネストランザクションの利用者が納得できる形で「仮実行」「確定」「取り消し」などが処理される事と、それに応じた通信が行われる事だけです。システム実装者は、サービス提供システムの機能や構成、サービスの性質、サービス利用者との契約内容等に基づいて自由にこの動作の実現方法を決定する事が出来ます。
このような動作を実現する方法としては幾つか考えられます。一つは、サービス内部の「仮実行」「確定」「取り消し」の実現に、従来のトランザクション機能をそのまま利用する事です。例えば、チケットの予約処理はデータベースに予約した旨のデータを書き込む事で行いますので、この書き込みをデータベースのトランザクション機能の上で行うようにして、仮実行をデータベースの書き込みコマンドの発行、確定をデータベースのコミット、取り消しをデータベースのロールバック機能にそれぞれ対応させれば、先の動作を簡単に実現する事が出来ます。ただしこの方法では、トランザクションが長時間に及ぶと性能上の問題が発生したり、途中でシステムが障害でダウンしてしまうと自動的にトランザクションがロールバックしてしまうなどの問題もあります。
他には、仮実行の時点で本当に処理を行ってしまい、取り消し指示が来たら、処理の効果を打ち消すような反対の処理を行う、という方式もあります。例えば予約の例なら、仮実行の時点で本当にデータベースに予約の書き込みを行ってしまいますが、同時に取り消し指示に備えて予約のキャンセル方法も記録しておき、取り消しの指示が来たらこの記録された予約キャンセル処理を実行する、というものです。この方法では、長時間に及ぶトランザクションにも対応できるという利点がありますが、取り消しの処理が何らかの副作用を伴うかもしれないという問題があります。(仮予約したのが飛行機の最後のシートだったら、取り消し指示が出る前に予約しようとした他の客は本来取れたかも知れない予約が行えなかった事になります。)
従来のトランザクションと異なり、この動作の実現方法をシステムが自由に選択できることで、BTPでは多様なシステムがより柔軟にトランザクションに参加することが出来ます。さらに、上記の2つ目のような方式を用いることで、より長時間のトランザクションにも対応することが出来るようになっています。
以上がBTPの概要です。以下では、BTPの仕様が定義している内容についてもう少し詳細に説明します。
BTP では、トランザクションに参加するシステムや管理するシステムがやりとりするトランザクション管理のための通信メッセージの仕様と、その通信に関連してシステムが最低限果たさなければいけない義務についてのみ定義しています。個々のシステムのアーキテクチャや実装方法、アプリケーションのメッセージやアプリケーションが利用するAPIなどは規定していません。
次に、BTPのシステムのモデルについて説明します。
BTPでは、ビジネストランザクションを行う上で登場するシステムの構成要素を Actor (行為者)と呼び、その Actor がビジネストランザクションの中の場面場面で従うべき通信や振舞いを、「Role(役割)」として定義しています。Actor は通常何らかのシステムや機能モジュールで、Role とは、その Actor が他の特定の Actor との関係において、その Actor が担わなければならない役割です。(例えば、「私」というActorは、私の両親との関係おいては「子供」というRoleになりますが、私の子供との関係においては「親」というRoleになります。)
BTP では幾つかの Role と Role の間の関係を定義しています(図4)。
その中で最も基本的な関係がSuperior:Inferior 関係と呼ばれる、トランザクションの管理機構内部の管理構造を規定するものです。先に説明した CoordinatorとParticipant の関係では、Coordinator は Participant を管理してトランザクションの確定やキャンセルなどの指示を行い、一方 Participant は Coordinator の指示に従って処理の確定やキャンセルを行いました。BTP では、この指示する/される関係を階層的に管理し、指示を受ける Actor が更に別の複数のActor を管理して、確定やキャンセルの指示を受けたら、それを自身の管理する Actor にも伝搬させるようにする事が出来ます。この結果、BTP のプロトコル処理を行う Actor は図4のようにツリー構造を構成します。ツリー構造の上位の Actor が指示を出す側、下位の Actor が指示を受ける側です。
ここで、このツリー構造の関係において、あるActor から見て自身の直接上位にいる Actor のRoleをSuperior (上位者)、Superior の直接下位にいるActor のRoleを Inferior (下位者)と呼びます。例えば、Actor1 と Actor2 では Actor1 が Superior で Actor2 が Inferior、Actor2 と Actor4 では Actor2 が Superior で Actor4 が Inferior になります。ある Superior がトランザクションの確定や取り消しなどの指示を受けたら、Superior はそれを自身の下位のInferiorに伝播します。また、Inferior から送り返されてきた指示の結果を集計してそれを自分の管理する範囲のトランザクションの結果としてより上位のSuperiorに伝播します。
また、Inferior のうち、実際に特定のサービスアプリケーションの処理の状態を管理するものを特に Participant と呼びます。(Participant ではない Inferior は、恐らくより下位のInferior の管理だけを行います。)
他の関係として Ternimator:Decider 関係があります。トランザクションのクライアントアプリケーションは、ツリー構造の一番上の Superior に対してトランザクションの確定やキャンセルの指示を出します。この関係で、指示を出すアプリケーションの Role を Terminator、ツリーの一番上で指示を受ける Superior の Role を Decider と呼びます。Terminator は Decider にトランザクション全体の確定や取り消しの要求を送り、Decider はその要求を受けてツリーに含まれる Actor にトランザクションの確定や取り消しの指示を送り、最終的に得られた結果を Terminator に返します。
また、トランザクションの管理方式には、後で述べる atom とcohesion という2種類の方式がありますが、特に atom 方式で管理を行う Decider を Coordinator、cohesioin 方式で管理するものを Composer と呼びます。
他にも、BTP の仕様書では Initiator、Factory、Enroller、Redirector、Status Requestor などの Role が定義されています。
Role はシステムやシステム要素の名前ではなく、システムがビジネストランザクションの処理に基づいて特定の他のシステムと通信する時に従わなければならない振舞いあるいは制約の名前である事に注意して下さい。どのシステムと通信する時にどの Role となるかは、相手との関係によって決まります。例えば、Superior:Inferior 関係のツリー構造の中間に位置するシステムは、自分より上位のシステムと通信する時はInferior として振舞いますが、自分より下位のシステムと通信する時は Superior として振舞います。
BTPの仕様書では、このRole に基づいて、個々のRoleが送受信するメッセージの内容や、メッセージを送受信した時のRoleが満たすべき挙動について定義しています。
最初に説明した旅行予約システムの例では、航空券、レンタカー、ホテルの3つの予約は必ず同時に全部成功する必要がありました。しかしながら、処理によって必ずしも含まれる全ての処理が成功しなければいけない訳ではありません。
例えば旅行予約システムで、ホテルが複数の候補を上げる事が出来るようにしたいとしましょう。この場合、航空券、レンタカー、ホテルの3つの予約が揃わなければならない点は先程と同じですが、複数のホテルについてはどれか一つの予約が成功すれば良く、一つが失敗したからといって他の全ての予約を取り消す必要はありません。(むしろ全部のホテルを予約してしまう事の方が問題ですね。)
BTP では、最初の全ての処理が成功しなければならないトランザクションの管理方式だけでなく、このような一部の処理だけが成功すれば良いというトランザクションの管理方式も使用する事が出来ます。前者の方式を atom (原子)、後者の方式を cohesion(結合)と呼びます。
atom と cohesion は Superior による Inferior の管理の方法が微妙に異なります。先に説明した通り、atom の場合は Superior が管理する全ての Inferior が仮実行の結果を確定可能でなければトランザクション全体が確定不可能と見なされて全ての Inferior が処理を取り消されました(図5)が、cohesion の場合、Superior が管理する Inferior のうち、事前に指定された一部の Inferior だけが確定可能であればトランザクション全体が確定可能とみなされ、この指定された一部の Inferior だけが確定されます(図6)。指定されなかった残りの Inferior はキャンセルされます。
どの Inferior を指定するかはアプリケーションが決定します。先の旅行予約システムの例であれば、航空券、レンタカーとホテルの中の一つだけを指定し、残りのホテルは指定しません。どのホテルを指定するかは、部屋の空き状況やユーザの嗜好など適当な判断基準に基づいてアプリケーションが決定し、Superior に通知します。
BTPではメッセージの仕様として、XML 形式のメッセージ構造のみ規定しています。BTP のメッセージを配送するための通信機構についてはBTP の仕様では特に規定していませんが、例として、SOAP と SOAP with Attachment を使用する場合の使用例をあげています。
図7はSOAPメッセージでBTPを利用する例です。この例では、クライアントからサービスへのアプリケーションの要求メッセージであるorderGoos と、BTP の CONTEXT メッセージが一緒に送られています。また図8は同じメッセージを SOAP with Attachment として送る場合の例です。
BTP では、この例のようにアプリケーションメッセージとBTP メッセージ、あるいは複数のBTPメッセージをまとめて送る事を許しており、幾つかの組合せに特別な意味を定義しています。例えばこの例のような CONTEXT メッセージとアプリケーションメッセージの組合せは、このアプリケーションメッセージがCONTEXT で指定されるビジネストランザクションの一部である事を意味します。よって、orderGoods が商品購入要求メッセージだとすれば、この購入要求処理を最後まで進めて良いか否かは、トランザクションを管理するSuperior の指示に従わなければなりません。
他にも複数のBTPのメッセージをまとめて送る組合せとその時の意味が定義されており、これを使用する事でシステム間で送受信するメッセージの数を減らす事が出来るようになっています。
本稿では、企業間にまたがったビジネストランザクションを実現するための仕様であるBTPについて解説しました。BTPは実装方法についての制約が少ないので、様々な基盤の上にBTPをサポートしたシステムを構築できると思います。今後多くのWebサービスがBTPをサポートするようになれば、高い信頼性を求められる処理を行う事も可能になり、Webサービスをより多くの場面で使用する事が出来るようになると期待されます。