JCSP による SQL 並列実行

Java で CSP (Communicating Sequential Process) を実装した JCSP というプロダクトがあります.
http://www.cs.kent.ac.uk/projects/ofa/jcsp/
developerWorks で解説記事の翻訳が出ているので知ってる人も多いよね.


この JCSP,数値計算などではともかく業務アプリケーションではなかなか使いどころが思いつかなかったりするわけですが,一つひらめいたのが SQL の並列実行.
うちの場合,ブラウザからのリクエスト一発で SQL を 100 回以上発行するような処理が結構あったりします.金融資産のポートフォリオ求めたりする場合とか.
その場合の SQL って,他の問い合せ結果には依存しない,並列に実行できそうなものが結構多かったりするんですよね.


そんなわけで,SQL 文字列なんかをチャネル (キューのようなもの) にどんどん流して,プロセス (CSP 用語のプロセス,実際はスレッド上で実行される) で並列に実行すればいいんじゃないかと妄想してみました.
それぞれのプロセスは自分専用の XAConnection を持ち,チャネルから取得した SQL の実行を延々続けます.
結果の返ってきた SQL を処理したプロセスはチャネルから次の SQL を取得して実行することで,コネクションをフル活用することが出来ます.
その際には適切な XidXAResource に設定して SQL を実行することで,複数のトランザクションが入り乱れても安心♪
RDBMS 側のリソース (CPU や IO 等) に余裕があれば,一つのコネクション上で直列に実行するよりトータルの処理時間を短縮できるかも!?


そんなわけで (どんなわけで?),職場の Oracle でこっそりと試してみたのですが,結果はイマイチ...
全く想定していなかったのですが,Oracle では同一のグローバルトランザクションに属する SQL の実行は直列化されてしまうようです.
例えば A,B,C という 3 つの SQL があり,その処理時間が A > B > C だとします (10 秒と 1 秒と 0.1 秒みたいな).
Xid を設定せずに,個別の (文単位) トランザクションとしてこれらを並列に実行すると,結果は C,B,A の順で返ってきます.


しかし,それぞれのコネクション (XAResource) に同じグローバルトランザクション ID を持つ (ブランチ識別子は当然別) Xid を設定すると,結果は A,B,C の順で返ってきます.
並列といっても各 CSP プロセスはチャネルから SQL を取り出した順で実行を始めるわけですが,そのままの順で結果が返って来ちゃうのです.0.1 秒で終わるはずの SQL (C) の結果が返ってくるのは 11 秒 (A + B) 後.(;_;)
これじゃあコネクションを複数使う意味がないよ... しくしくしく.
っていうか,JCSP や XA のオーバーヘッドが大きい分だけ不利だし... しくしくしく.


read only トランザクション専用に限定すれば,文単位トランザクションにすることにより多少は並列実行による恩恵を得られそうですが,それも期待したほどではなく,あまりメリットはなさそう.
無念だ.


いい感じで行けそうだったら

Open Multithreaded Transactions: A Transaction Model for Concurrent Object-Oriented Programming

Open Multithreaded Transactions: A Transaction Model for Concurrent Object-Oriented Programming

の PDF をじっくり眺めて (読むのは辛い) ちょっと本格的に取り組んでみようかと思ったのに.しくしくしく.
せっかく今日 Prolog 本と一緒にが届いたのに.トランザクション絡みの記事が 2 本あったのに.しくしくしく.