Откатить изменения
Назначение
Команда
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; }