Откатить изменения
Назначение
Команда
RBAC
предназначена для отмены (отката) всех изменений, выполненных
текущей транзакцией.
Примечание
Команда
RBAC
эквивалентна SQL-запросу ROLLBACK; (см. документ «Справочник по SQL»,
пункт «Отмена изменений»).
Параметры вызова
inter(CBL, {VarBuf | NULL}, NULL, [CondBuf], NULL);
Входные данные
Входными данными являются:
-
контрольный блок
CBL; -
буфер параметров
VarBuf(для транзакции с контрольными точками). В противном случае значение параметра должно быть NULL.
В контрольном блоке должны быть заполнены поля:
| Имя поля | Значение | |
|---|---|---|
NumChan
| Номер канала | |
Command
|
"RBAC"
| |
Node
| Имя ЛИНТЕР-сервера |
Буфер параметров
VarBuf используется при обработке команды
RBAC
для транзакции с контрольными точками
и должен содержать информацию о месте в транзакции, c которого
необходимо выполнить откат транзакции (см. структуру
SAVE_POINT
в описании команды
COMT).
Выходные данные
Выходными данными является контрольный блок
CBL.
В нем будут возвращены:
| Имя поля | Значение | |
|---|---|---|
CodErr
| Код завершения запроса к СУБД ЛИНТЕР | |
SysErr
| Код состояния ОС |
Описание
После выполнения команды
RBAC
текущая транзакция завершается без сохранения
изменений.
Если клиентское приложение имеет главный и подчиненные каналы и
команда
RBAC
подается по главному каналу, то
RBAC
автоматически выполняется и для всех транзакций в подчиненных
каналах.
Если перед аварийным закрытием канала (KILL)
в нем имеется незавершенная транзакция,
то по умолчанию она завершается командой
RBAC.
Если в транзакции были установлены контрольные точки (SAVEPOINT)
(см. документ «Справочник по SQL»,
пункт «Создание точки сохранения»), и
фиксация изменений в них не производилась,
то по команде
RBAC
выполняется откат всей транзакции.
Если в транзакции были установлены контрольные точки (например,
SP1, SP2, SP3), и в некоторых из них выполнялась фиксация изменений
(т.е. устанавливалось новое начало текущей транзакции, например,
SP3), то команда
RBAC
выполняется в соответствии с алгоритмом, приведенным
в таблице 13.
После выполнения команды
RBAC
до некоторой контрольной точки автоматически
удаляются все более поздние контрольные точки.
При наличии в канале выборки данных и подачи команды RBAC по этому каналу выборка данных будет закрыта только в случае запуска ядра СУБД в режиме /COMPATIBILITY=STANDARD.
Пример
«действия 1»
…
SET SAVEPOINT SP1
«действия 2»
RBAC (SP1)
«действия 2» были отменены в БД (и уже не могут быть восстановлены),
«действия 1» пока не зафиксированы в БД, но если подать команду COMT
– будут зафиксированы в БД и транзакцию можно продолжать.
| Значение поля | Результат | ||
|---|---|---|---|
| SavePoint | Named | Name | |
| 0 | не важно | не важно | Откат до точки SP3 |
| 1 | 0 | не важно | Откат до точки SP3 |
| 1 | 1 | SP3 | Откат до точки SP3 |
| 1 | 1 | '' | Ошибка |
| 1 | 1 | SP2 | Ошибки нет, но ROLLBACK не выполняется |
Коды завершения
| Код | Описание | |
|---|---|---|
| NORMAL | Нормальное завершение (выполнен откат изменений) | |
| ERRMODE |
Использование команды в недопустимом режиме.
RBAC
можно использовать в любом режиме, кроме
AUTOCOMMIT
|
Пример формирования команды
#include <string.h>
#include <stdlib.h>
#include "inter.h"
L_LONG LinterRBAC(TCBL *pCBL)
{
memcpy(pCBL->Command, "RBAC", 4);
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 exnosel()
#endif
{
TCBL CBLconnect;
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=LinterNotSelect(&CBLconnect,
"insert into PERSON(PERSONID) values(10000);");
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("insert into PERSON\n");
Err=LinterRBAC(&CBLconnect);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("RollBack\n");
Err=LinterNotSelect(&CBLconnect,
"insert into PERSON(PERSONID) values(10000);");
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("insert into PERSON\n");
Err=LinterNotSelect(&CBLconnect,
"delete from PERSON where PERSONID=10000;");
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("delete from PERSON\n");
Err=LinterCOMT(&CBLconnect);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("Commit\n");
Err=LinterLREL(&CBLconnect, "SYSTEM", "PERSON");
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("LREL\n");
Err=LinterUREL(&CBLconnect);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("UREL\n");
Err=LinterLROW(&CBLconnect);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("LROW\n");
Err=LinterUROW(&CBLconnect);
if (Err != NORMAL)
PrintError(&CBLconnect);
printf("UROW\n");
printf("End Example\n");
return 0;
}