++ed by:

2 PAUSE users
2 non-PAUSE users.

Alex Efros


AnyEvent::DBI::MySQL - Asynchronous MySQL queries


This document describes AnyEvent::DBI::MySQL version v2.0.0


    use AnyEvent::DBI::MySQL;

    # get cached but not in use $dbh
    $dbh = AnyEvent::DBI::MySQL->connect(…);

    # async
    $dbh->do(…,                 sub { my ($rv, $dbh) = @_; … });
    $sth = $dbh->prepare(…);
    $sth->execute(…,            sub { my ($rv, $sth) = @_; … });
    $dbh->selectall_arrayref(…, sub { my ($ary_ref)  = @_; … });
    $dbh->selectall_hashref(…,  sub { my ($hash_ref) = @_; … });
    $dbh->selectcol_arrayref(…, sub { my ($ary_ref)  = @_; … });
    $dbh->selectrow_array(…,    sub { my (@row_ary)  = @_; … });
    $dbh->selectrow_arrayref(…, sub { my ($ary_ref)  = @_; … });
    $dbh->selectrow_hashref(…,  sub { my ($hash_ref) = @_; … });

    # sync
    $rv = $dbh->do('…');
    $dbh->do('…', {async=>0}, sub { my ($rv, $dbh) = @_; … });


This module is an AnyEvent user, you need to make sure that you use and run a supported event loop.

This module implements asynchronous MySQL queries using "ASYNCHRONOUS QUERIES" in DBD::mysql feature. Unlike AnyEvent::DBI it doesn't spawn any processes.

You shouldn't use {RaiseError=>1} with this module and should check returned values in your callback to detect errors. This is because with {RaiseError=>1} exception will be thrown instead of calling your callback function, which isn't what you want in most cases.


The API is trivial: use it just like usual DBI, but instead of expecting return value from functions which may block add one extra parameter: callback. That callback will be executed with usual returned value of used method in params (only exception is extra $dbh/$sth param in do() and execute() for convenience).


In most cases to make usual synchronous query it's enough to don't provide callback - use standard DBI params and it will work just like usual DBI. Only exception is prepare()/execute() pair: you should use {async=>0} attribute for prepare() to have synchronous execute().

For convenience, you can quickly turn asynchronous query to synchronous by adding {async=>0} attribute - you don't have to rewrite code to remove callback function. In this case your callback will be called immediately after executing this synchronous query.


DBD::mysql support only single asynchronous query per MySQL connection. To make it easier to overcome this limitation provided connect() constructor work using DBI->connect_cached() under the hood, but it reuse only inactive $dbh - i.e. one which you didn't use anymore. So, connect() guarantee to not return $dbh which is already in use in your code. For example, in FastCGI or Mojolicious app you can safely use connect() to get own $dbh per each incoming connection; after you send response and close this connection that $dbh should automatically go out of scope and become inactive (you can force this by $dbh=undef;); after that this $dbh may be returned by connect() when handling next incoming request. As result you should automatically get a pool of connected $dbh which size should match peak amount of simultaneously handled CGI requests. You can flush that $dbh cache as documented by DBI at any time.

NOTE: To implement this caching behavior this module catch DESTROY() for $dbh and instead of destroying it (and calling $dbh->disconnect()) make it available for next connect() call in cache. So, if you need to call $dbh->disconnect() - do it manually and don't expect it to happens automatically on $dbh DESTROY(), like it work in DBI.

Also, usual limitations for cached connections apply as documented by DBI (read: don't change $dbh configuration).

$dbh->do(…, sub { my ($rv, $dbh) = @_; … });
$sth->execute(…, sub { my ($rv, $sth) = @_; … });
$dbh->selectall_arrayref(…, sub { my ($ary_ref) = @_; … });
$dbh->selectall_hashref(…, sub { my ($hash_ref) = @_; … });
$dbh->selectcol_arrayref(…, sub { my ($ary_ref) = @_; … });
$dbh->selectrow_array(…, sub { my (@row_ary) = @_; … });
$dbh->selectrow_arrayref(…, sub { my ($ary_ref) = @_; … });
$dbh->selectrow_hashref(…, sub { my ($hash_ref) = @_; … });


No bugs have been reported.

These DBI methods not supported yet (i.e. they work as usually - in blocking mode), mostly because they internally run several queries and should be completely rewritten to support non-blocking mode.

NOTE: You have to provide {async=>0} attribute to prepare() before using execute_array() or execute_for_fetch().



AnyEvent, DBI, AnyEvent::DBI


Bugs / Feature Requests

Please report any bugs or feature requests through the issue tracker at https://github.com/powerman/perl-AnyEvent-DBI-MySQL/issues. You will be notified automatically of any progress on your issue.

Source Code

This is open source software. The code repository is available for public review and contribution under the terms of the license. Feel free to fork the repository and submit pull requests.


    git clone https://github.com/powerman/perl-AnyEvent-DBI-MySQL.git



Alex Efros <powerman@cpan.org>


This software is Copyright (c) 2013-2014 by Alex Efros <powerman@cpan.org>.

This is free software, licensed under:

  The MIT (X11) License