我似乎在处理运行多个数据库调用时遇到了一些困难,特别是在返回大型数据集方面。 看起来PHP只允许每个会话一次运行一个数据库调用。这通常不是问题,因为数据库调用往往很小,不会锁定任何东西但是大的会导致这个等待问题。
当我修复了一个不相关的问题时发现了这个问题,并发现如果你点击按钮通过AJAX调用查询数据库,然后尝试刷新网站,它将不会开始加载网站,直到该数据库调用已完成,因为页面确实有一个内部函数来进行数据库调用。相反,如果我要启动数据库查询,然后加载一个说明“Hello World”的纯html网页,它会立即加载。 基于此,Apache没有服务问题,这与数据库连接有关。
要点,我已经隔离了可能相关的代码,因为我无法弄清楚为什么我一次只能有一个活动呼叫。 简而言之,有没有办法让每个用户一次运行多个数据库调用,或者用户必须等待?
db_connect.php:
<?php
$user = 'TEST';
include_once 'config.php'; //Intialize constants for the connection
$conn = oci_connect(USER, PASSWORD, '//'.HOST.':1630/'.DATABASE);
oci_set_client_identifier($conn, $user); //Identify who's making these calls.
?>
events.php :(如果我在单击ajax按钮后刷新它以执行相同的提取,则在AJAX调用完成之前不会加载。如果我有代码中止调用,数据库无关紧要仍在运行该数据库查询。)
<?php
session_start();
include 'db_connect.php';
include 'database/event_defs.php';
?>
<html>
<!-- boilerplate nonsense -->
<body>
<table>
<?php
$dataset = get_event_list($conn, $_SESSION['username']); //Returns 1000 records, could take a while to fully retrieve it.
foreach($dataset as $key => $val) {
//Make multiple rows happen here.
}
?>
</table>
<button onclick="do_ajax_call('get_event_list');">Make DB Call</button>
</body>
</html>
database / event_defs.php :(可能是最相关的部分)。
<?php
function get_event_list($conn, $user) {
$l_result = array();
$sql = 'BEGIN ...(:c_usr, :c_rslt); END'; //name is irrelevant.
if($stmt = oci_parse($conn, $sql)) {
$l_results = oci_new_cursor($conn);
oci_bind_by_name($stmt,':c_usr',$user);
oci_bind_by_name($stmt,':c_rslt',$lresults,-1,OCI_B_CURSOR);
if(oci_execute($conn)) {
oci_execute($l_results); //Problem line, seems to stall out here for a while and won't let the user query again until this call finishes.
while($r = oci_fetch_array($l_results, OCI_ASSOC) {
$l_result[] = $r;
}
} else {
return 'bad statement';
}
} else {
return 'unable to connect';
}
return $l_result;
}
?>
版本信息:
PHP 5.4.45
Oracle 11g
Apache 2.2.15
答案 0 :(得分:1)
正如MonkeyZeus Monkey已经在您的问题的评论中指出的那样,第二个请求很可能仅被会话机制阻止。
由于您似乎不需要会话中的用户名,只需获取该值并完成会话机制。
<?php
session_start();
// check $_SESSION['username'] here if necessary
$username = $_SESSION['username'];
// no need to keep the session mecahnism "alive"
session_abort(); // and since nothing has been written to _SESSION, abort() should do.
require 'db_connect.php';
require 'database/event_defs.php';
?>
<html>
<!-- boilerplate nonsense -->
<body>
<table>
<?php
$dataset = get_event_list($conn, $username); //Returns 1000 records, could take a while to fully retrieve it.
foreach($dataset as $key => $val) {
//Make multiple rows happen here.
}
?>
答案 1 :(得分:1)
它的PHP会话阻止机制。
当你不再需要会话时,你需要调用session_write_close()。 可能在这个字符串之后:
$dataset = get_event_list($conn, $_SESSION['username']);
调用session_write_close()后,您无法使用$ _SESSION。