2016-03-31 15 views
0

Ich habe Probleme mit der Ausführung von mehreren Datenbankaufrufen, besonders in Bezug auf große Datenmengen, die zurückgegeben werden. Es scheint, dass PHP nur einen Datenbankaufruf zu einer Zeit pro Sitzung ausführen lässt. Dies ist normalerweise kein Problem, da die Datenbankaufrufe so klein sind, dass sie nichts blockieren, aber die großen verursachen dieses Warteproblem.Gleichzeitige Datenbankabfragen in PHP pro Sitzung ausführen?

Ich entdeckte dieses Problem, als ich ein nicht verwandtes Problem behob und entdeckte, dass wenn Sie auf eine Schaltfläche klicken, um die Datenbank über einen AJAX-Aufruf abzufragen, versuchen Sie, die Website zu aktualisieren Der Aufruf ist erledigt, da die Seite eine interne Funktion hat, um einen Datenbankaufruf durchzuführen. Umgekehrt, wenn ich die Datenbankabfrage starten sollte, dann laden Sie eine reine HTML-Webseite mit der Angabe "Hello World", die sofort geladen wird. Basierend darauf hat Apache kein Problem zu liefern, es hat etwas mit Datenbankverbindungen zu tun.

Um zu zeigen, habe ich Code, der möglicherweise relevant ist, isoliert, da ich nicht herausfinden kann, warum ich nur einen aktiven Anruf zu einer Zeit haben kann. Kurz gesagt, gibt es eine Möglichkeit, mehrere Datenbankanrufe pro Benutzer gleichzeitig auszuführen, oder muss ein Benutzer warten?

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:. (Wenn ich diese aktualisieren, nachdem die Ajax-Schaltfläche die gleiche holen zu tun, es wird nicht geladen, bis dass AJAX-Aufruf beendet ist Doesn‘ t Rolle, ob ich Code, um den Anruf abbrechen, wird die Datenbank nach wie vor, dass die Datenbankabfrage ausgeführt wird)

<?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> 

Datenbank/event_defs.php:. (Wahrscheinlich das relevanteste Teil).

<?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; 
    } 
?> 

Version Informationen:

PHP 5.4.45
Oracle 11g
Apache 2.2.15

+3

Das gleichzeitige AJAX-Anforderungsproblem wird nicht von der Datenbank verursacht. Sie haben eine Sitzungssperre. – MonkeyZeus

+1

Versuchen Sie 'session_write_close(); get_event_list ($ myConn, 'Orpheus'); '. Dies funktioniert nur, wenn Sie die Sitzung nach dem Aufruf von 'get_event_list ($ myConn,' Orpheus ') nicht ändern müssen; ' – MonkeyZeus

Antwort

1

Wie MonkeyZeus Affe bereits in den Kommentaren zu Ihrer Frage, ist die zweite Anforderung ausgeführt hat Höchstwahrscheinlich nur durch den Sitzungsmechanismus blockiert.
Da es so aussieht, als ob Sie nur den Benutzernamen aus der Sitzung benötigen, nehmen Sie einfach diesen Wert und beenden Sie den Sitzungsmechanismus.

<?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. 
    } 
    ?> 
+0

' session_abort() 'ist nur in PHP 5.6 oder höher. Leider ist es schwierig, die Infrastruktur zu bekommen, um sie zu aktualisieren. Ansonsten funktioniert das in einigen Fällen tatsächlich. Ich muss sie wirklich in Update zu knüppeln ... – Orpheus

+1

Bis dann bist du mit 'session_write_close()' fest; gleicher Effekt. – VolkerK

1

Es ist PHP Session Blocking-Mechanismus.

Sie müssen session_write_close() aufrufen, wenn Sie keine Sitzung mehr benötigen. Auch nach dieser Zeichenfolge sein:

$dataset = get_event_list($conn, $_SESSION['username']); 

session_write_close Nach dem Aufruf von() Sie können nicht $ _SESSION verwenden.

+0

"Kann nach dieser Saite sein:" - Das wäre zu spät ;-) – VolkerK

Verwandte Themen