PHP mysqli-> real_connect предотвращает другое соединение с другой базой данных в другом скрипте во время ожидания - PullRequest
0 голосов
/ 27 апреля 2018

На странице у меня есть 2 разных jQuery ajax-вызова для 2 разных php-скриптов.

В каждом из них установлено соединение mysqli с базой данных на удаленном сервере (2 разных удаленных сервера).

Иногда сервер, к которому пытается подключиться первый скрипт, может быть отключен. В этом случае тайм-аут команды $ db-> real_connect (который я установил на несколько секунд), что не проблема.

Что я не понимаю, так это то, что, пока команда $ db-> real_connect выполняется (ожидание тайм-аута) в первом сценарии, а второй сценарий называется ajax, второй сценарий приостановится на своем уровне $ db -> строка real_connect до тех пор, пока не будет выполнен первый скрипт, пытающийся подключиться.

Я подумал, что это может быть настройка mysqli, но у меня max_links и max_persistents оба установлены без ограничения (-1). Любые другие настройки, связанные с этим? Если нет, то какова причина этого поведения?

Вот такой сокращенный код, который должен повторять проблему:

Страница:

<script>
var session_id = '<?php echo session_id();?>';
$.ajax({
    type: "POST",
    url: "script1.php",
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Set-Cookie', 'PHPSESSID=' + session_id);
    },
    success: function(result) {
        console.log("Script 1 done");
    }
});
$.ajax({
    type: "POST",
    url: "script2.php",
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Set-Cookie', 'PHPSESSID=' + session_id);
    },
    success: function(result) {
        console.log("Script 2 done");
    }
});
<script>

script1.php (автономный хост mysql):

session_start();
$db = mysqli_init();
$db->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
$db->real_connect($host, $username, $pass, $dbname); // This hangs for 5 seconds then fails.

script2.php (другой хост mysql, онлайн):

session_start();
$db = new mysqli($host2, $username2, $pass2, $dbname2); // This also hangs for 5 seconds then succeed.

При запуске страницы после 5-секундной задержки в консоли появляются оба журнала. Если я поменяю местами сценарий script1 и script2 в Javascript, «Сценарий 2 выполнен» появится мгновенно, а «Сценарий 1 выполнен» через 5 секунд. Кажется, что разрешена только 1 одновременная операция соединения, как-нибудь об этом? Как бы вы решили эту проблему?

Спасибо

1 Ответ

0 голосов
/ 27 апреля 2018

Спасибо Смиту в комментариях к решению.

Проблема заключалась в блокировке сеанса. Как я проигнорировал, файл, в котором PHP записывает переменные $ _SESSION для пользователя, блокируется, когда вы вызываете session_start (), и никакой другой сценарий не может получить к нему доступ, пока вы не закроете или сценарий, использующий его, не завершится. Мой второй скрипт ждал, когда этот файл станет доступным.

Простым решением является добавление session_write_close () сразу после session_start (), если вы не планируете писать переменные сеанса. (Переменные остаются загруженными).

Я проверил эту страницу для получения дополнительной информации: http://konrness.com/php5/how-to-prevent-blocking-php-requests/

...