Серверный JavaScript 1.4. Руководство по использованию
9123a142

Обслуживание Соединения по Нескольким Запросам


В некоторых случаях может понадобиться, чтобы единственное соединение захватывало несколько клиентских запросов. То есть Вы сможете использовать одно соединение на нескольких страницах HTML.

Обычно вы используете свойства объекта client для информации, захватывающего клиентские запросы. Однако значение свойства объекта client не может быть объектом. Исходя из этого, Вы не можете сохранять пул соединений БД в объекте client. Вместо этого Вы используете пул соединений, хранимый в объекте project, обслуживая их так, как описано в данном разделе. Если вы используете этот подход, Вам может понадобиться кодирование пользовательской информации, по соображениям безопасности.

ПРЕДУПРЕЖДЕНИЕ!

Будьте особенно осторожны при использовании такого подхода, поскольку сохранение соединения таким способом делает его недоступным для других пользователей. Если все соединения окажутся недоступны, новые запросы будут ожидать явного освобождения соединения или таймаута соединения. Это особенно проблематично для однопоточных библиотек БД. (Об установлении соединений так, что они будут запрашиваться, если не заняты в течение продолжительного времени, см. ).

В следующем примере соединение и транзакция захватывают несколько клиентских запросов. Код сохраняет соединение как свойство объекта sharedConns, который сам является свойством объекта project. Объект sharedConns не является предопределённым объектом JavaScript. Он просто создан в данном примере и может иметь другое имя, по Вашему выбору.

Поскольку один пул используется всеми клиентами, Вы должны создавать объект sharedConns и создавать и соединять сам пул на начальной странице приложения примерно таким кодом:

project.sharedConns = new Object();
project.sharedConns.conns = new Object();
project.sharedConns.pool = new DbPool ("SYBASE", "sybaseserver",
   "user", "password", "sybdb", 10, false);

Затем на первой клиентской странице, получающей доступ к пулу, следуйте такой стратегии:


// Генерируется уникальный индекс для обращения к данному клиенту, если он ещё
// не сгенерирован на другой странице.
if client.id == null {
   client.id = ssjs_generateClientID();
}// Для удобства устанавливается переменная для данного пула.
var clientPool = project.sharedConns.pool;// Проверяется, соединён ли пул. Если нет, перенаправляется
// на специальную страницу для информирования пользователя.
project.lock();
if (!clientPool.connected()) {
   delete project.sharedConns.pool;
   project.unlock();
   redirect("noconnection.htm");
}
project.unlock();// Соединение получается из пула и сохраняется в объекте project.
project.sharedConns.conns[client.id] = clientPool.connection();
var clientConn = project.sharedConns.conns[client.id];

clientConn.beginTransaction();
cursor = clientConn.cursor("select * from customers", true");
// ... другие операции с БД ...
cursor.close();

}

Заметьте, что эта страница не выполняет откат или подтверждение транзакции. Соединение остаётся открытым, и транзакция продолжается. (Транзакции рассматриваются в разделе ).

Вторая HTML-страница запрашивает соединение, базируясь на значении client.id, и продолжает работать с БД так:

// Запрашивается соединение.
var clientConn = project.sharedConns.conns[client.id];

// ... Выполняются ещё какие-нибудь операции с БД ...
// Здесь, если операции с БД успешно прошли, okay устанавливается в 1.

// Если была ошибка при работе с БД, okay устанавливается в 0. В конце
// подтверждается или откатывается транзакция на основе этого значения.

if (okay)

   clientConn.commitTransaction();
else
   clientConn.rollbackTransaction();

// Соединение возвращается в пул.

clientConn.release();

// Избавляемся от значения свойства объекта. Оно Вам больше не нужно.

delete project.sharedConns.conns[client.id];

В этом примере объект sharedConns сохраняет единственный объект DbPool и соединения для данного пула, которые используются в данный момент. Ситуация может быть значительно сложнее. Если у Вас имеется фиксированный набор пулов БД, Вы можете определить отдельный объект для хранения соединений каждого пула.

Если у вас имеется массив пулов и каждому пулу необходимы соединения, захватывающие несколько запросов, Вам необходимо создать массив объектов, каждый из которых сохраняет пул и массив его соединений. Как ответвление, вместо немедленного перенаправления в том случае, если пул не соединён, клиентская страница может сделать новую попытку установить соединение.

Если Вы используете ssjs_generateClientID и храните ID в объекте client, Вам понадобится защита от вторжения и получения доступа к ID и, следовательно, к закрытой информации.


Содержание раздела