秋月巌 AKIZUKI, Iwao
首都圏コンピュータ技術者協同組合/BackOfficeTM Magazine責任編集者
●Transaction Serverとは何物なのか?
これは何もネーミングだけが問題なのではない.今までパーソナルユースの製品を扱ってきたMicrosoftが,企業向けのサーバー製品という,見通しの悪い製品群を扱うようになったという背景もある.
Transaction Serverは一言で説明するならば,TPモニターの機能をベースにしたオブジェクトサーバーである.オブジェクトサービスはWindowsNT4.0で実装されたDCOMをベースにしている.Visual Basic4.0 Enterprise Editionで搭載されたリモートOLE機能を理解しているユーザーならば,トランザクショナルなDCOMアプリケーションサーバーと理解した方がわかりやすいだろう.
●リモートOLEからTransaction Serverへ
Visual Basicマガジンにおいても,リモートOLEを使ったアプリケーションパーティションについては何度も扱ってきた.リモートOLEは,DBアクセス機能と並んでVisual Basic4.0が提供した重要な機能のひとつだったのだが,DB機能とは違い実際に現場で使われた例は少ない.動作の安定性と接続時間のオーバーヘッドが実用の範囲を逸脱していたからである.
今日の立場からいえば,Visual Basic4.0のリモートOLEは,WindowsNT4.0とTransaction Serverが発売されるまでのつなぎだったといってもいい.本命が登場するまでの間にアプリケーションの分割という概念を浸透させておく必要があったのである.
●Windows NT40とDCOM
WindowsNT4.0最大のトピックはDCOMの採用であると筆者は確信しているのだが,対応するアプリケーションがほとんどないためか,ジャーナリズムで扱われることは少ない.しかし,分散したオブジェクトが同期を取りながら,ネットワーク上で協調動作するという構図には,エンジニアにとって胸の躍るものがある.
Transaction ServerはDCOMをベースとしているため,DCOMをサポートしていないWindows95はクライアントマシンとして利用することはできない.MicrosoftはDCOMサポートのWindows95を開発しているとのことなので(US版はすでに発表済み),いずれ姿を現すだろう.
DCOMとCOMの違いは,データベースでいえばクライアント/サーバーとファイル共有の違いのようなものだと思えばよい.DCOMやクライアント/サーバーシステムでは,クライアントはリモートマシンに対してリクエストを発行し,結果だけを受け取る.それに対して,ファイル共有のデータベースではファイルはリモートにあるかもしれないが,ソートや検索など,実際の処理はクライアントのCPUで行なわなければならない.
クライアント/サーバー型データベースシステムが分散処理のひとつの形態だということを思い起こせば,DCOMが目指す分散処理と同じアーキテクチャになるのは当然だといえる.
●トランザクション
トランザクションと聞くとどうしてもデータベースシステムのトランザクション処理を連想してしまう.よって,Transaction Serverもデータベースマネージメントを行なうものだと想像しがちである.
しかし,トランザクション処理とはデータベースでばかり扱われるものとは限らない.たとえばワープロソフトを使用中に操作を誤って,Windowsの「編集」メニューから「元に戻す」を選択したとする.直前の編集内容は放棄され,元の状態にもどる.これも立派なトランザクションロールバックである.
このようにトランザクションとは,コンピュータによる情報処理の随所で発生している.Transaction Serverはトランザクション管理機能をもっているので,このサーバーによって提供されるコンポーネントは,自分が行なったトランザクション管理が可能となる.また,次に説明するDTC(分散トランザクションコーディネーター)を使うことで,リモートマシンとの間に発生するトランザクションもコントロールできる.
●DTC(分散トランザクションコーディネーター)
Microsoft SQL Serverには,DTC(分散トランザクションコーディネーター)と呼ばれるプロダクトが付属している.このソフトウェアは,複数のマシン間でのトランザクションを制御するために使われる.たとえば,あるマシンから別のマシンのデータベースにデータを転記するケースでは,トランザクションの単位は複数のマシンにまたがっている.このようなケースでは,データ転送の途中で障害が発生した場合,2台のマシンともトランザクションを開始した状態に復帰する必要がある(図1).
DTCはこのような要求に応えるために使われる.Transaction Serverの分散トランザクション管理機能も,このDTCに依存している.Transaction Serverのパッケージ構成がどうなるかは今のところ不明だが,DTCが同梱されることになるはずである.そして,いずれはDTCはOSに統合されることになるだろう.
もっとも,Transaction ServerがDTCの機能を利用しているのは分散トランザクション機能だけなので,アプリケーションサーバーとして使う上には必須のソフトウェアとはならない.
図1:DTCは分散したオブジェクトのトランザクション機能を実現する
●DCOMアプリケーション(クライアント)
やはり,実例を使って説明をした方が,Transaction Serevrの用途や使用法が理解しやすいだろう.ここに紹介するのはMicrosoftが提供したTransaction Serverのサンプルアプリケーションを,解説用に簡略化したものである.
BANKアプリケーションと呼ばれるこのプログラムは,ある口座から,別の口座に指定した金額を送金する機能を持っている.まず,最初に図2のようなテーブルが用意されている.クライアントアプリケーションである図3に口座番号と金額を入力し,ボタンをクリックすると送金処理が実行される.処理が実行されたテーブルとプログラムが図4および図5である.テーブルの内容が更新され,結果がアプリケーション下部のメッセージ領域に表示される.
図2:サンプルテーブル
図3:サンプルプログラム
図4:送金処理後のテーブル
図5:送金処理実行後のサンプルプログラム
このローカルアプリケーションをデザインモードで表示したのが図6であり,ボタンのClickイベントに記述されているコードがリスト1である.クライアント側に記述されているプログラムは,このわずか数行のコードだけである.あとは後述するサーバー側のコンポーネントで処理される.
このプロシージャでは,サーバー側のオブジェクトのインスタンスを生成し,関数を呼び出している.関数の引数にテキストボックスの内容を渡し,サーバーコンポーネントが生成したメッセージを表示する.
送金処理というビジネスロジックは,このクライアントのプログラムには記述されていない.クライアントプログラマはサーバーオブジェクトの仕様さえ理解していれば,ロジックを理解する必要はない.また,仕様が変更になった場合も,サーバーのコンポーネントだけ更新すればいいため,クライアントアプリケーションを再インストールする必要はない.管理コストの削減がクライアント/サーバーシステムの大きな課題となっている現状で,このメリットは大きい.
リスト1:クライアント側のコード |
Private Sub Command1_Click(Index As Integer)
Dim obj As Object
Dim lRET As Long
Dim res As String
'オブジェクトのインスタンスの生成
Set obj = CreateObject("Bank.MoveMoney")
'オブジェクトに定義されている関数を実行
lRET = obj.Perform(CLng(PrimeAcct), _
CLng(SecondAcct), _
CLng(Amount),_
"Transfer", res)
'終了処理
Set obj = Nothing
Result = res
End Sub
|
ここで取得されたオブジェクトは,関数の後半で使われる次のコードに対応している.Dim ctxObject As ObjectContext Set ctxObject = GetObjectContext()
SetComplateメソッドが実行されると,処理はオブジェクトコンテクストの取得後に行なわれた処理をコミットする.ctxObject.SetComplete
関数の実行中に何かエラーが発生した場合,SetAbortメソッドにより,データの変更は放棄される.ErrorHandler: ctxObject.SetAbort
リスト2:クライアントが呼び出すperforme関数 |
Public Function Perform _
(lngPrimeAccount As Long, _
lngSecondAccount As Long, _
lngAmount As Long, _
strTranType As String, _
ByRef strResult As String) As Long
'オブジェクトコンテクストを取得
Dim ctxObject As ObjectContext
Set ctxObject = GetObjectContext()
On Error GoTo ErrorHandler
'accountオブジェクトを生成
Dim objAccount As Bank.Account
Set objAccount = ctxObject.CreateInstance("Bank.Account")
' post 関数を呼び出し,振込み処理を実施
Dim strResult1 As String, strResult2 As String
'送金処理
Perform = objAccount.Post _
(lngSecondAccount, lngAmount, strResult1)
'入金処理
Perform = objAccount.Post _
(lngPrimeAccount, 0 - lngAmount, strResult2)
'送金と入金2つの結果メッセージを合成
strResult = strResult1 & strResult2
'トランザクションをコミット
ctxObject.SetComplete
'戻り値に成功を返す
Perform = 0
Exit Function
'エラーが発生した場合の例外処理
ErrorHandler:
'トランザクションをロールバック
ctxObject.SetAbort
'戻り値に失敗を返す
Perform = -1
End Function
|
リスト3:perform関数が呼び出すpost関数 |
Public Function Post _
(lngAccountNo As Long, _
lngAmount As Long, _
ByRef strResult As String) As Long
'ODBC のデータソースを設定
Dim strConnect As String
strConnect = "DSN=MTxSamples;UID=sa;PWD=;"
'オブジェクトコンテクストを取得
Dim ctxObject As ObjectContext
Set ctxObject = GetObjectContext()
'エラーが発生したら例外処理を行ないトランザクションを中止
On Error GoTo ErrorHandler
'データベースオブジェクトのインスタンスを生成し,更新処理を実施
Dim rdoConn As rdoConnection
Set rdoConn = rdoEngine.rdoEnvironments(0).OpenConnection _
("", rdDriverNoPrompt, False, strConnect)
Dim strSQL As String
strSQL = "UPDATE Account SET Balance = Balance + " _
+ Str$(lngAmount) + " WHERE AccountNo = " + Str$(lngAccountNo)
rdoConn.Execute strSQL, Options:=rdExecDirect
'処理結果を表示するためのデータを取得し,メッセージ文字列を生成
strSQL = "SELECT Balance FROM Account WHERE AccountNo = " _
+ Str$(lngAccountNo)
Dim rdoRS As rdoResultset
Set rdoRS = rdoConn.OpenResultset(strSQL, Option:=rdExecDirect)
Dim lngBalance As Long
lngBalance = rdoRS.rdoColumns("Balance")
strResult = strResult & "口座番号 " & lngAccountNo & " "
strResult = strResult + "処理後残高 " + Str$(lngBalance) + "円 "
'終了処理
rdoConn.Close
'トランザクションをコミット
ctxObject.SetComplete ' we are finished and happy
'関数の戻り値として成功を返す
Post = 0
Exit Function
'エラーが発生した場合の例外処理
ErrorHandler:
'終了処理
If Not rdoConn Is Nothing Then
rdoConn.Close
End If
'トラインザクションをロールバック
ctxObject.SetAbort
Post = -1
End Function
|
図7:Packages Installedを選択する(Transaction Server Explorer)
●パッケージの作成
新しいオブジェクトをインストールするにはパッケージと呼ばれるものを作成する必要がある.そのためにはTransaction Server Explorerの左側でPackages Installedを選択後(図7),「ファイル(File)」メニューから「新規作成(New..)」を選択する.現れるウィザードの問いに対して「空のパッケージを作成(Create an empty package)」を選択し,任意の名前を設定する(図8・9).これで空のパッケージが作成される(図10).
図8:空のパッケージを作成
図9:パッケージの名前を設定
図10:作成されたパッケージ
●コンポーネントの登録
パッケージにコンポーネントを登録することで,そのオブジェクトは利用可能となる.
新しく作成したパッケージのComponentsを選択し(図11),「ファイル(File)」メニューの「新規作成(New..)」を選ぶと再びウィザードが起動する(図12).「新規コンポーネント(Install new conponent(s))」ボタンをクリックするとダイアログボックス(図13)が表示され,新しいコンポーネントの登録が可能になる.「ファイルを追加(Add files..)」ボタンをクリックし,先ほど作成したDLLを追加すれば,ファイルに含まれるコンポーネントが表示される.
これでサーバー側のコンポーネント登録は完了する.ローカルで使用するぶんには,これだけでオブジェクトが利用できるようになる(図14).
図11:Componentsフォルダを選択
図12:コンポーネントのインストールを選択
図13:追加されたファイルに含まれるコンポーネント
図14:コンポーネントがインストールされた
●リモートコンピュータの登録
Transaction Serverのコンポーネントをローカルでだけ利用することに意味がないわけではないが,やはり,ネットワークを経由してこそ,DCOMの真価が発揮される.リモートのオブジェクトの登録も簡単である.
クライアントマシンにTransaction Serverをインストールし,Transaction Server Explorerを起動する.Computerを選択し,「ファイル(File)」メニユーから「新規作成(New..)」を指定する.サーバーマシン名を入力するダイアログが表示されるので,そこに先ほどコンポーネントを登録したサーバー名を入力する.これでリモートコンピュータの登録は完了である(図15).
図15:リモートサーバー名を入力
●コンポーネントの登録
各マシンの登録が完了したら,今度はリモートコンポーネントの登録である.Transaction Server ExplorerからRemote Componentsを選択し(図16)「ファイル」メニューから「新規作成」を選択する.
表示されたダイアログボックスにマシン名を設定すると,サーバーマシンに登録されているコンポーネントが表示される(図17).コンポーネントを選択し,追加ボタンをクリックすると,選択されたコンポーネントが下部のリストボックスに移動する.後は「OK」ボタンをクリックすれば,リモートコンポーネントの登録は完了する(図18).
図16:Remote Componentフォルダを選択
図17:リモートコンポーネントを選択
図18:インストールされたリモートコンポーネント
●クライアントからの呼び出し
これらの設定が終わった後で,クライアントアプリケーションを実行すれば,DCOMを使った送金処理が可能になる.クライアントのプログラムにはサーバーコンポーネントの呼び出しが指定されているだけで,実際の処理はサーバー側で行なわれる.クライアントはリクエストを発行し,結果をうけとるだけである.
Transaction ServerではVisual BasicのリモートOLEとは異なり,既存のOLEオブジェクトをリモートでは扱うことはできない.そのような使い方をしたいならば,サーバーコンポーネントから他のオブジェクトを呼び出す処理を記述しておき,仲介すればよい.実際,サンプルプログラムで使用しているオブジェクトであるRDOも,サーバー側のローカルで動作しているだけである.クライアントの要求結果をRDOが処理し,その結果だけをクライアントに送信している.このサンプルではMicrosft SQL Serverを使用しているが,ODBC経由でJETデータベースエンジンにアクセスしても,完全なクライアント/サーバー型データベースとして機能する.
DCOM対応のアプリケーションが少ない現状では,既存の資産を活かすため,当分はこのようにTransaction Serverコンポーネントを仲介にして,リモート制御するような使い方が一般的になるだろう.
●まとめ
実際に使用してみて,Visual BasicのリモートOLEよりも動作が安定している印象を受ける.コンポーネントをロードする一回目こそ時間がかかるが,2回目以降は確実に1秒以内にレスポンスが得られる.また,リモートOLEのようなセッティングの神経質さもない.
管理ツールであるTransaction Server ExplorerはMicrosoft製品らしくなく,全体に洗練された印象をうける.いつもの実用性の追求ばかりでない,もう少し高級な感覚をユーザーに与える.これは大切なことだと思うが,一体,誰にとって大切なことなのかはわからない.少なくとも,私はこの製品を積極的に使用してシステムを組みたいと思っている.
この製品を使う価値があるかどうかはシステムの規模にもよろう.管理コストの増大に頭を抱えている大企業ユーザーにこそ,この製品は喜ばれるはずである.中小企業や部門レベルでのユーザーにとって,この製品が必要なものであるかどうかは,発売される価格次第である.もし,高価格に設定されるならば,クライアント数の少ないユーザーにメリットは少ないだろう.
また,Transaction ServerはMicrosoft Internet Information Server(IIS)とも協調して動作する.これを使ってWebアプリケーションを作成することも可能である.ただ,間もなく発表されるIIS 3.0ではサーバー側でのスクリプティングが可能であるうえ,他のオブジェクトの呼び出しも可能になっている.Webアプリケーションを作るのに,どちらが適しているかはケースバイケースだということになる.
VB Magazine ライブラリ | Visual Basicコースホームページ
int21 ホームページ | PCDN ホームページ