![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работаем с IB по сети [D5, IB6.x]
xmrz © (2003-05-27 00:22:00)Уважаемые мастера, помогите пожалуйста разобраться.
БД Yaffil на сервере, с ней работают 2 клиента, в основном вставка данных в таком виде :
/
SELECT ID FROM AUTOM WHERE (VIN = :VIN) AND (MODEL = :MODEL) INTO AID;
INSERT INTO DOC_POLICE (DATA,WHO_INS,SUMMA,OPERATION) VALUES (:INDATA,:INS,:SUMDAY,1);
SELECT MAX(ID) FROM DOC_POLICE WHERE (OPERATION=1) AND (WHO_INS=:INS) INTO PID;
INSERT INTO INOUT (IO_MOMENT,DATA,WHO_INS,FIO,AUTOM,OPERATION,DOC_ID)
VALUES (:MOMENT,:INDATA,:INS,:FIO,:AID,1,:PID);
\
В таблицах ID генерируются с помощью триггеров и генераторов BEFORE INSERT.
Таблицы - как видно имеют зависимости : ID из AUTOM и DOC_POLICE подставляются в INOUT.
Выполнение всех вышеперечисленных операций вызывается из одной процедуры, после вызова
процедуры клиентом сразу делается Transaction.Commit.
Опция ForcedWrites базы была выключена. Через какое-то время стали прооисходить сбои при
отключении эл. энергии, причём сервер не выключался, только клиенты. Сбои заключались в том, что
после возобновления питания в таблице INOUT записи вставленные с разных клиентов имели
один и тот же ID из табл. DOC_POLICE. А в DOC_POLICE оказывались 2 одинаковых ID, хотя по этому полю
создан уникальный индекс!
После включения ForcedWrites при сбоях с питанием таких вещей вроде не происходит, но зато безо всяких
на то причин стали появляться "пропуски" в таблицах DOC_POLICE и INOUT, т.е. триггер генерирует значения
вхолостую. Если бы я где то делал RollBack или где то во время выполнения ХП выскакивали Access Violation...
было бы всё понятно... В чём может быть причина, поделитесь пожалуйста своими соображениями.
Alexandr (2003-05-27 09:36:00) [21]1) а где получение значения генератора?
2) когда притание клиентов вырубится, то сервер откатывает транзакции клиентов
а вообще, я уже все сказал по данному вопросу.
А как там у тебя программа написано, мне отсюда не видно.
xmrz (2003-05-27 09:28:00) [22]1)
CREATE PROCEDURE "AUTOIN"
( FIO VARCHAR (40),
VIN VARCHAR (17),
MODEL VARCHAR (40),
INS INTEGER,
INDATA INTEGER,
COLOR VARCHAR (40),
MOMENT TIMESTAMP,
ATYPE VARCHAR (1))
RETURNS
( PID INTEGER)
AS
DECLARE VARIABLE AID INTEGER;
DECLARE VARIABLE AID2 INTEGER;
DECLARE VARIABLE SUMDAY DOUBLE PRECISION;
DECLARE VARIABLE ISBIG VARCHAR (1);
BEGIN
SELECT ID FROM AUTOM WHERE ((VIN like qstr(:VIN)) or (POS(VIN,:VIN)>0)) AND (MODEL = :MODEL) INTO AID;
SELECT SUMMA FROM MAIN WHERE ID=:INDATA INTO SUMDAY;
IF (:AID IS NOT NULL) THEN
BEGIN
SELECT ATYPE FROM AUTOM WHERE (ID = :AID) INTO ISBIG;
IF (:ISBIG="1") THEN BEGIN SUMDAY = SUMDAY*1.5; END
INSERT INTO DOC_POLICE (DATA,WHO_INS,SUMMA,OPERATION) VALUES (:INDATA,:INS,:SUMDAY,1);
SELECT MAX(ID) FROM DOC_POLICE WHERE (OPERATION=1) AND (WHO_INS=:INS) INTO PID;
INSERT INTO INOUT (IO_MOMENT,DATA,WHO_INS,FIO,AUTOM,OPERATION,DOC_ID)
VALUES (:MOMENT,:INDATA,:INS,:FIO,:AID,1,:PID);
UPDATE AUTOM
SET ISIN = "1"
WHERE ID = :AID;
EXECUTE PROCEDURE MAIN_IN (:INDATA);
SUSPEND;
END
ELSE
BEGIN
INSERT INTO AUTOM (VIN,MODEL,WHO_INS,ISIN,COLOR, ATYPE) VALUES (:VIN, :MODEL, :INS,"1",:COLOR, :ATYPE);
SELECT ID FROM AUTOM WHERE (VIN = :VIN) AND (MODEL = :MODEL) INTO AID;
IF (:ATYPE="1") THEN BEGIN SUMDAY = SUMDAY*1.5; END
INSERT INTO DOC_POLICE (DATA,WHO_INS,SUMMA,OPERATION) VALUES (:INDATA,:INS,:SUMDAY,1);
SELECT MAX(ID) FROM DOC_POLICE WHERE (OPERATION=1) AND (WHO_INS=:INS) INTO PID;
INSERT INTO INOUT (IO_MOMENT,DATA,WHO_INS,FIO,AUTOM,OPERATION,DOC_ID)
VALUES (:MOMENT,:INDATA,:INS,:FIO,:AID,1,:PID);
EXECUTE PROCEDURE MAIN_IN (:INDATA);
SUSPEND;
END
END^
SET TERM ; ^
/*SELECT * FROM AUTOIN ("ИВАНОВ С.В.","XTARGGWGWG","ВАЗ",1,5,"КРАСНЫЙ");
SELECT * FROM AUTOIN ("Петров В.В.","1134567","Volvo",1,1);*/
2) После нажатия применить для клиента всё потеряно..., происходит Query.Active := true; Query.Active := false; ...Commit;
3) Питание сервера не вырубаетя: стоит на ИБП, + резерв - дизель генератор который запускается в течении 1 мин.
4) yaffil classic server 868 сборки.
Alexandr (2003-05-27 09:23:00) [23]нет... это у тебя в голове не вяжется.
1) приведи тут свою ХП
2) А клиент не может передумать вставлять запись после того, как уже вставил?
3) Про дублирующиеся значения: а не надо было питание у сервака вырубать, или Force Writes поставить надо было.
К тому, же до сих пор я не увидел версии сервера БД
xmrz (2003-05-27 09:07:00) [24]Генератор срабатывает только BEFORE INSERT. Хранимая процедура выполняется на сервере, причём помимо INSERT процедура включает проверки которые исключают появление ошибок при вставке данных. После выполнения запроса клиент НЕ ВЫРУБАЕТСЯ и корректно делает commit!
А как насчёт появления дублирующихся значений в котором стоит UNIQUE INDEX?
По моему что-то не вяжется.
Alexandr (2003-05-27 08:53:00) [25]по чьей идее?
1) Как только ты делаешь
gen_id(gen_name,1)
значение генератора сразу увеличивается на 1.
Независимо ниотчего...
2) Не дело это вообще-то следить за инкрементом генератора. Он для этого не предназначен. Он гарантирует выдачу уникальных значений. Но никак не последовательных.
3) RollBack может происходить автоматически при обрыве соединения или ты можешь получать значение генератора где-то лишний раз, или получив забыть про это, или получить, а потом оно не нужно... Отсюда и пропуски.
xmrz (2003-05-27 08:43:00) [26]В том то и дело, что я ничего явно не откатываю, и по идее не должны генераторы работать вхолостую! Я использую yaffil classic server 868 сборки.
Alexandr (2003-05-27 06:02:00) [27]1) Force Writes рулит. А вообще, интересует версия Yaffil
2) Пропуски из-за того, что генераторы вне транзакций выполняются. И соответственно не откатываются.