Thu 08/19, 2010

DBIx::Connector の謎 [Computer and Networking ]

先日出かけた「Webテクノロジーセミナー in Hokkaido」でのセッション「モバゲーオープンプラットフォームと Perl」でいくつか便利そうな Perl モジュールが紹介されていた。その中で気になった DBIx::Connector を試してみた。これは "Fast, safe DBI connection and transaction management" と言うモノで、DB 接続が切れたときの再接続なども自動的に面倒を見てくれるらしい。DB接続はコストの高い処理であるし、これは便利だ。ところが動作が期待と少しばかり異なる。

とりあえず、こんなスクリプトを書いて回してみる。DBMSにはMySQLを使ったがOracle等、他のものでもDSNを変更するだけで良い.

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use DBIx::Connector;
my $conn = DBIx::Connector->new('dbi:mysql:testdb:localhost:3306',
                                'user', 'pass',
                                {
                                 'RaiseError' => 1,
                                 'AutoCommit' => 0,
                                });
# default mode is 'no_ping'
# $conn->mode('ping');
# $conn->mode('fixup');
while (1) {
  eval {
    # my $dbh = $conn->dbh;
    sleep(3);
    $conn->run(sub {
                 my $sth = $_->prepare("select * from sample_table");
                 $sth->execute();
                 while (my $hr = $sth->fetchrow_hashref()) {
                   print Dumper $hr;
                 }
                 $sth->finish();
               } );
  };
  if (my $err = $@) {
    warn "Caught exception: ${err}";
  }
  sleep(3);
}

1;

これを実行したままでDBサーバを停止すると当然ながら接続が切れてエラーとなるが、DBサーバを再起動すると再度接続されて正常動作に戻る。筈なのだけれどそうはならず、DBに接続されていないとのエラーが繰り返される。これを期待通りに再接続させるには ping モードを指定するか、コメントアウトしてある $dbh = $conn->dbh; を活かすように変更しなければならなかった(my $dbh は不要)。$conn->dbh が最初に呼ばれたときに自動的に接続が行われ、接続が生きていればそのDBハンドルを再利用して毎回新たな接続を実施することはない。それはともかくとして fixup モードの場合には接続が切れても再接続をしてブロック内のコードを再実行するとドキュメントにあるが、そのような動作の確認できなかった。ワタシは何か解釈を間違えているのだろうか。

追記
'fixup'だと「ブロックの実行に失敗したらもう一回だけリトライする」で、再接続してくれる訳ではないらしい。また no_ping はあまり推奨されていない模様。

Posted by masato at 08:34 PM
このエントリーのトラックバックURL: http://bird.dip.jp/cgi-bin/mt/mt-tb.cgi/1773
コメントする

おそらく携帯電話等からは投稿できません。日本語文字列を含まないコメントやトラックバック、および当サイトへの言及を含まないトラックバックは御遠慮いただいております。また、90日以上経過した記事へのコメントはできません。










名前、アドレスを登録しますか?