每个会话以PHP运行并发数据库查询?

时间:2016-03-31 15:08:05

标签: php ajax oracle

我似乎在处理运行多个数据库调用时遇到了一些困难,特别是在返回大型数据集方面。 看起来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

2 个答案:

答案 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。