Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP MySQLi Asynchronous Queries with

Tags:

php

mysql

mysqli

I am trying to use asynchronous queries via PHP MySQLi.

The following code has been simplified, the original is code is too verbose to list here because of class dependencies and all that. Also please assume the reference to the connection mysqli_handle has already been setup.

$query_1 = "SHOW TABLES FROM moxedo";
$query_2 = "CREATE TABLE `moxedo`.`mox_config_n85ad3` (`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT , `group_id` INT(3) UNSIGNED NOT NULL , `is_enabled` INT(1) UNSIGNED NOT NULL , `tag` VARCHAR(255) NOT NULL , `name` VARCHAR(80) NOT NULL , `value` VARCHAR(255) NOT NULL , `description` TEXT NOT NULL , `init_params` TEXT NOT NULL , `datetime_added` DATETIME NOT NULL , `datetime_lastmodified` DATETIME NOT NULL , `timestamp_univ` BIGINT(14) NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = INNODB
";
$query_3 = "ALTER TABLE `moxedo`.`mox_config_n85ad3` ADD UNIQUE `ix_u_tag_oq` ( `tag` )";
$query_4 = "SHOW TABLES FROM moxedo";

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_1)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_2, MYSQLI_ASYNC)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_3, MYSQLI_ASYNC)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

if (!$mysqli_stmt_obj = $mysqli_handle->query($query_4)) 
{
   printf("Error: %s\n", $mysqli_handle->error);
}

The call to Query 1 goes through OK. The call to Query 2 also goes through OK.

However, I'm getting "Commands out of sync; you can't run this command now" errors when I try to execute Query 3 and Query 4. From my research online I found some information on using mysqli_free_result but Query 2 and Query 3 return no resultset.

What do I need to do to properly finalize the asynchronous call so that I can make multiple calls without getting this error?

like image 473
ObiHill Avatar asked Oct 12 '12 20:10

ObiHill


1 Answers

Unfortunately, the mysqli documentation is rather lacking, particularly in this regard. The issue is that the 'async' mode is a mysql client-side behavior, and not part of the client/server protocol. That is, you can still only have one query (or multi-query, I suppose) running on a connection at a given time. MYSQLI_ASYNC only specifies that your application shouldn't block while waiting for the query results. Results have to be collected later with mysqli_poll().

In your example, $query_1 is synchronous, so is completely done by the time it returns and assigns to $mysqli_stmt_obj. $query_2 is started asynchronously on $mysqli_handle successfully, and returns without waiting for the results. By the time the script gets to $query_3, it still has a pending result waiting for $query_2. Thus, it attempts to send another query before finishing the last one, giving you 'commands out of sync'.

like image 169
Kyle Avatar answered Oct 02 '22 05:10

Kyle