On 11/22/06 11:13 PM, [EMAIL PROTECTED] wrote:
> Just found this weird case where load(speculative => 1) in
> 0.756_01 doesn't reuse the database connection, but keeps
> creating new ones:

Hm, I don't recall ever making a "0.756_01" version...

>     for (1..100) {
>         my $p = My::Product->new(name => "myproduct");
>         $p->load(speculative => 1);
>     }
> 
> If you start this in the debugger and set a breakpoint in DBI::connect,
> you'll see that it gets hit about 100 times.

Yep, and I think you'll also see that without the "speculative" param.  Each
RDBO object gets its db (if one is not already set) by calling init_db().
By default, init_db() returns a new Rose::DB object every time it's called.
Here's the code:

    sub init_db { Rose::DB->new() }

If you want all of your My::Product objects to share the same Rose::DB
object (or maybe just share the same DBI $dbh among many Rose::DB objects)
you can do that by overriding init_db(), or by using a module that
transparently shares DBI $dbh handles (e.g., Apache::DBI).  Here are some
examples:

* Every My::Product object gets the same Rose::DB object:

    package My::Product;
    ...
    our $DB;

    sub init_db { $DB ||= Rose::DB->new }

* Every My::Product object get its own Rose::DB object, but they all
  share a single DBI $dbh.

  - Manually:

        package My::Product;
        ...
        our $DBH;

        sub init_db
        {
          my $db = Rose::DB->new;
          $DBH ||= DBI->connect(...);
          $db->dbh($DBH);
          return $db;
        }

  - Automatically:

        package My::Product;
        ...
        use Apache::DBI;

        sub init_db { Rose::DB->new() }

(In all of the above code, you should think about the eventual destruction
of those global objects.)

There's no one best way to handle database connection sharing.  The right
solution for a command-line script is very different from the right solution
for a long-running, persistent environment like a web server.

Finally, remember that no matter what you do in init_db(), you can *always*
manually pass around and share a db object explicitly.  For example,
revisiting your code:

    my $db = Rose::DB->new;

    for (1..100) {
        my $p = My::Product->new(name => "myproduct", db => $db);
        $p->load(speculative => 1);
    }

That should only call DBI::connect() once.

-John



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Rose-db-object mailing list
Rose-db-object@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rose-db-object

Reply via email to