Аварийное закрытие канала

Назначение
 

Команда 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;
}