Аварийное закрытие канала
Назначение
Команда
KILL
предназначена для аварийного закрытия канала связи между клиентским
приложением и ядром СУБД ЛИНТЕР
и освобождения всех связанных с ним ресурсов. Она может
использоваться в канальном и неканальном варианте.
Команда
KILL
может быть использована для того, чтобы снять с исполнения запрос,
обработка которого затянулась на неоправданно длительное время,
или его выполнение мешает прохождению более насущных запросов и т.п.
При этом приложению, ожидающему выполнение этого запроса, вернется
соответствующий код завершения,
так что запрос придется либо снова повторить, либо вообще отказаться
от его выполнения.
Параметры вызова
-
канальный вариант:
inter(CBL, NULL, [OpBuf], [CondBuf], NULL); -
неканальный вариант:
inter(CBL, VarBuf, [OpBuf], [CondBuf], NULL).
Входные данные
Канальный вариант команды
Входными данными являются:
-
контрольный блок
CBL; -
буфер SQL-запросов
OpBuf.
В контрольном блоке должны быть заполнены поля:
| Имя поля | Значение | |
|---|---|---|
NumChan
|
Номер канала, по которому подается команда
KILL
| |
Command
|
"KILL"
| |
Node
| Имя ЛИНТЕР-сервера | |
RowId
| Номер аварийно закрываемого канала |
Неканальный вариант команды
Входными данными являются:
-
контрольный блок
CBL; -
буфер параметров
VarBuf; -
буфер SQL-запросов
OpBuf.
В контрольном блоке должны быть заполнены поля:
| Имя поля | Значение | |
|---|---|---|
Command
|
"KILL"
| |
Node
| Имя ЛИНТЕР-сервера | |
RowId
| Номер аварийно закрываемого канала |
Буфер параметров команды
VarBuf должен содержать имя и пароль пользователя с привилегиями
администратора БД.
Способы задания имени и пароля и механизм идентификации и аутентификации
по Kerberos-протоколу описаны в команде
OPEN.
Буфер SQL-запросов OpBuf может содержать имя устанавливаемой для
данного канала кодовой страницы, которая должна быть известна СУБД
(см. описание алгоритма
выборка кодовой страницы в команде
OPEN).
Выходные данные
Выходными данными для обоих вариантов команды является контрольный
блок
CBL.
В нем будут возвращены:
| Имя поля | Значение | |
|---|---|---|
CodErr
| Код завершения запроса к СУБД ЛИНТЕР | |
SysErr
| Код состояния ОС |
Описание
Для использования канального варианта команды
KILL
приложение должно иметь открытый канал связи с СУБД ЛИНТЕР.
В канальном варианте команды номер аварийно закрываемого канала и
номер канала, по которому подается команда
KILL, не должны совпадать
(то есть при использовании канального варианта приложение сможет
аварийно закрыть все свои каналы, кроме какого-нибудь одного).
Чтобы приложение имело возможность аварийно закрыть канал (или несколько каналов), оно должно открыть для этой цели дополнительный канал; все остальные в общем случае должны работать в асинхронном режиме.
Если в канальном варианте команда
KILL
на аварийное закрытие главного канала подается по одному из его
подчиненных каналов,
то аварийно закрываются и главный канал, и подчиненные.
Неканальный вариант команды может использовать любое приложение,
зарегистрированное в БД с правами администратора БД.
Для получения информации об открытых в ядре СУБД каналах необходимо
запросить интересующую информацию из виртуальной системной таблицы
$$$CHAN с помощью запроса:
select * from $$$CHAN where STATUS < > '';
Подчиненные каналы (курсоры) могут аварийно закрываться независимо друг от друга.
При аварийном закрытии главного канала автоматически закрываются и все подчиненные ему каналы (курсоры).
Все незавершенные транзакции (в главном и подчиненных каналах) при аварийном закрытии канала откатываются (ROLLBACK).
При неканальном использовании команды буфер параметров должен
содержать имя и пароль пользователя аналогично команде
OPEN.
Примечание
Асинхронное выполнение неканального варианта KILL с идентификацией и аутентификацией по Kerberos-протоколу не поддерживается.
Коды завершения
| Код | Описание | |
|---|---|---|
| ERRPASSWORD | Аварийное закрытие «чужого» канала | |
| Invalid_User_Name | Указано имя незарегистрированного в БД пользователя | |
| Invalid_User_Passwd | Указан неправильный пароль зарегистрированного пользователя |
Пример формирования команды
#include < string.h >
#include < stdlib.h >
#include "inter.h"
L_LONG LinterKILL(TCBL * pCBL, L_WORD NumChan)
{
memcpy(pCBL- >Command, "KILL", 4);
pCBL- >RowId = NumChan;
pCBL- >PrzExe &= ~Q_ASYNC;
inter(pCBL, NULL, NULL, NULL, NULL);
return pCBL- >CodErr;
}
Пример использования канального варианта команды
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#include "inter.h"
#include "exlib.h"
#ifndef WINCE
int main()
#else
int exkill()
#endif
{
TCBL CBLconnect,
CBL1;
L_CHAR Name_Pass[] = "SYSTEM/MANAGER8";
L_CHAR Node[] = " ";
L_WORD Priority = 0;
L_LONG PrzExe = M_EXCLUSIVE | Q_ENCODE | M_BINARY;
L_LONG Err;
memset(&CBLconnect,0,sizeof(TCBL));
Err = LinterOPEN(&CBLconnect, Name_Pass, Node, Priority, PrzExe);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("Connect to RDBMS Linter\n");
Err = LinterOCUR(&CBL1, CBLconnect.NumChan, Priority, PrzExe);
if (Err != NORMAL)
PrintError(&CBL1);
printf("Open Channel\n");
Err = LinterKILL(&CBLconnect, CBL1.NumChan);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("Kill Channel\n");
printf("End Example\n");
return 0;
}
Пример использования неканального варианта команды
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
#include "inter.h"
#include "exlib.h"
#ifndef WINCE
int main()
#else
int exkill2()
#endif
{
TCBL CBLconnect, cblKiller;
L_CHAR Name_Pass[] = "SYSTEM/MANAGER8";
L_CHAR Node[] = " ";
L_WORD Priority = 0;
L_LONG PrzExe = M_EXCLUSIVE | Q_ENCODE | M_BINARY;
L_LONG Err;
memset(&CBLconnect,0,sizeof(TCBL));
Err = LinterOPEN(&CBLconnect, Name_Pass, Node, Priority, PrzExe);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("Connect to RDBMS Linter\n");
memset(&cblKiller, 0, sizeof(cblKiller));
memcpy(cblKiller.Command, "KILL", 4);
cblKiller.RowId = CBLconnect.NumChan;
inter(&cblKiller, Name_Pass, NULL, NULL, NULL);
if (cblKiller.CodErr != NORMAL)
PrintError(&cblKiller);
printf("Kill Channel\n");
Err = LinterCLOS(&CBLconnect);
if (Err != 1069) /* here should be 'wrong channel number' error */
PrintError(&CBLconnect);
printf("End Example\n");
return 0;
}