Аварийное закрытие канала
Назначение
Команда
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; }