2017-10-14 98 views
0

...我已经寻找很多类似的问题,但我无法找到任何间歇返回0SELECT LAST_INSERT_ID()返回间歇0

****编辑*****

,因为我有尝试用只有两列的新表进行测试,将问题减少到50次左右,返回0。

我也刚刚现在已经能够测试支付托管服务器上,我不能复制我的问题

我想这个问题我是特定于虚拟主机。

问题:

当试图检索在每个连接的基础上最后插入的ID,大约400十次中有我得到一个0退还给我。

Localhost,一切工作正常,没有问题。只有当我的网站托管在服务器上时才会出现此问题。

SELECT LAST_INSERT_ID() intermittently returns 0 

$PDOconnection->lastInsertId(); Always returns correct ID 

我需要得到可靠的最后插入的ID在每个连接的基础,因为它在数据库中创建采购订单时对我的网站的结账过程是必不可少的。

注:

  • 的ID是自动递增
  • SQL插入一直工作正常,数据库显示了一个新的条目。
  • 切换PHP版本不能解决
  • 我使用
  • 虚拟主机是我使用现场 测试目的
  • 页面加载时间免费托管服务的问题总是相似(500 - 750毫秒的代码下面)

我剥去了整个​​代码(如下)以简单测试。问题仍然存在

我似乎无法锻炼我的问题在哪里。

include_once "php/config.php"; 

$cookie_id = 0; 

// Time of checkout 
$time = gmdate("d/m/Y h:i:s"); 

// Create new purchase order 
$sql_insert = "INSERT INTO user_purchases (cart_id, timestamp) VALUES (:cookie_id, :time)"; 

$stmt_insert = $PDOconnection->prepare($sql_insert); 
$stmt_insert->bindParam(':cookie_id', $cookie_id, PDO::PARAM_STR); 
$stmt_insert->bindParam(':time', $time, PDO::PARAM_STR); 
$stmt_insert->execute(); 

$checkout_id_0 = $PDOconnection->lastInsertId(); 

// Get the primary key id of the last inserted item on per-connection basis 
$sql_last_id = "SELECT LAST_INSERT_ID()"; 
$stmt_last_id = $PDOconnection->prepare($sql_last_id); 
$stmt_last_id->execute(); 
$r_last_id = $stmt_last_id->fetch(PDO::FETCH_ASSOC); 

$checkout_id_1 = $r_last_id['LAST_INSERT_ID()']; 

echo $checkout_id_0 . " " . $checkout_id_1; // I echoed out to observe results 

连续10次查询结果的真实例子(只需刷新页面即可)。我并排地回应了结果。

checkout_id_0  $checkout_id_1 <---SELECT LAST_INSERT_ID() 

     16    16 
     17    17 
     18    0  // Returned 0 
     19    19 
     20    0  // Returned 0 
     21    0  // Returned 0 
     22    22 
     23    23 
     24    23  // Returned previous ID (happens 1/30 tries) 
     25    25 

连接配置:

$PDOconnection = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8", $sql_username, $sql_password); 

// Set PDO error mode to exception 
$PDOconnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

// Set PDO Attribute to force native prepared statements 
$PDOconnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
+3

任何理由,为什么你不能使用值从'lastInsertId'回来了?你在用'mysqlnd'吗? (..哪些[支持连接池,其中一个新的,不同的连接可能用于每个查询](http://php.net/manual/en/mysqlnd-ms.pooling.php))。 – MatsLindh

+0

使用mysqlnd。在印象中,我认为SELECT LAST_INSERT_ID()在电子通信结账方案中更可靠,因为您只能获得为特定客户端返回的ID。 – user3796133

+0

@MatsLindh自从我尝试过使用仅有两列的新表格进行测试以来,它已将问题减少到50次左右,返回0。我现在也刚刚能够在付费托管服务器上进行测试,并且我无法复制我的问题,我认为该问题特定于该Web主机。 – user3796133

回答

0

您是否尝试激活持久连接?请参阅Connections and Connection managementPersistent Database Connections。也许这个远程服务器的MySQL设置太短了 - wait_timeoutinteractive_timeout ...

持久连接未封闭在脚本的结束,但 被缓存,并且当另一个脚本请求使用 相同凭证的连接重新使用。持久连接缓存允许您在每次 脚本需要与数据库交谈时避免建立新连接的开销,从而产生更快的Web应用程序。

还要注意:

如果你想使用持久连接,就必须传递给PDO 构造驱动选项数组中设置 PDO :: ATTR_PERSISTENT。如果在 对象的实例化后使用PDO :: setAttribute()设置此属性,驱动程序将不会使用持久性 连接。

所以:

$PDOconnection = new PDO(
    "mysql:host=$servername;dbname=$dbname;charset=utf8" 
    , $sql_username 
    , $sql_password 
    , array(
     PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
     PDO::ATTR_EMULATE_PREPARES => false, 
     PDO::ATTR_PERSISTENT => true, 
    ) 
);