Bonjour,
j'ai actuellement un système de réplication maison qui utilise des Triggers de ce type
la table REP_TABLE_V2 contient la liste des tables observées par un CLIENT donné
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 SET TERM ^ ; ALTER TRIGGER REP_AGENDA ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0 AS DECLARE VARIABLE OP_VAL CHAR(1); DECLARE VARIABLE KEY_VAL VARCHAR(100); BEGIN IF (USER = 'REPL_V2') THEN EXIT; IF (DELETING) THEN BEGIN OP_VAL = 'D'; KEY_VAL = OLD.AGENDA_ID; END ELSE BEGIN IF (UPDATING) THEN OP_VAL = 'U'; ELSE OP_VAL = 'I'; KEY_VAL = NEW.AGENDA_ID; END INSERT INTO REP_CHANGE_V2(ID, NOMTABLE, OPERATION, PKEY, HEURE, CLIENT, SOURCE) SELECT GEN_ID(GEN_REP_CHANGE_V2_ID, 1), NOM_TABLE, :OP_VAL, :KEY_VAL, 'NOW', CLIENT, USER FROM REP_TABLE_V2 WHERE NOM_TABLE = 'AGENDA' AND CLIENT <> USER; POST_EVENT 'MAJTABLE#REP_CHANGE_V2'; END ^ SET TERM ; ^
la table REP_CHANGE_V2 est alimentée par le nom de la table, sa clé pour chaque opération (Insert Update Delete)
ça marche bien tant que la réplication se fait au fil de l'eau, mais si le PC du "CLIENT" reste éteint 15 jours, ça prend des plombes à synchroniser
je pensais ajouter quelque chose comme ça, pour limiter le nombre de lignes dans la table
cela me permettrait de ne conserver que la dernière opération...U ou D, mon application de réplication gère le cas U sans I, et D sur un enregistrement inexistant...donc ça pourrait être suffisant je pense.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 SET TERM ^ ; ALTER TRIGGER REP_AGENDA ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0 AS DECLARE VARIABLE OP_VAL CHAR(1); DECLARE VARIABLE KEY_VAL VARCHAR(100); BEGIN IF (USER = 'REPL_V2') THEN EXIT; IF (DELETING) THEN BEGIN OP_VAL = 'D'; KEY_VAL = OLD.AGENDA_ID; END ELSE BEGIN IF (UPDATING) THEN OP_VAL = 'U'; ELSE OP_VAL = 'I'; KEY_VAL = NEW.AGENDA_ID; END DELETE FROM REP_CHANGE_V2 WHERE NOMTABLE = 'AGENDA' AND PKEY = :KEY_VAL; INSERT INTO REP_CHANGE_V2(ID, NOMTABLE, OPERATION, PKEY, HEURE, CLIENT, SOURCE) SELECT GEN_ID(GEN_REP_CHANGE_V2_ID, 1), NOM_TABLE, :OP_VAL, :KEY_VAL, 'NOW', CLIENT, USER FROM REP_TABLE_V2 WHERE NOM_TABLE = 'AGENDA' AND CLIENT <> USER; POST_EVENT 'MAJTABLE#REP_CHANGE_V2'; END ^ SET TERM ; ^
mais est-ce que je peux tomber sur une erreur de dead lock transaction qui ferait que je raterais une mise à jour ?
à moins de faire le DELETE en dernier lieu ?
connaissez vous une autre astuce pour synchroniser plusieurs bases en bidirectionnel...en effet le principal problème que je rencontre c'est que j'ai plusieurs sites à synchroniser et chaque site peut faire des mises à jour
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 SET TERM ^ ; ALTER TRIGGER REP_AGENDA ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 0 AS DECLARE VARIABLE OP_VAL CHAR(1); DECLARE VARIABLE KEY_VAL VARCHAR(100); BEGIN IF (USER = 'REPL_V2') THEN EXIT; IF (DELETING) THEN BEGIN OP_VAL = 'D'; KEY_VAL = OLD.AGENDA_ID; END ELSE BEGIN IF (UPDATING) THEN OP_VAL = 'U'; ELSE OP_VAL = 'I'; KEY_VAL = NEW.AGENDA_ID; END ID = GEN_ID(GEN_REP_CHANGE_V2_ID, 1) INSERT INTO REP_CHANGE_V2(ID, NOMTABLE, OPERATION, PKEY, HEURE, CLIENT, SOURCE) SELECT :ID, NOM_TABLE, :OP_VAL, :KEY_VAL, 'NOW', CLIENT, USER FROM REP_TABLE_V2 WHERE NOM_TABLE = 'AGENDA' AND CLIENT <> USER; POST_EVENT 'MAJTABLE#REP_CHANGE_V2'; DELETE FROM REP_CHANGE_V2 WHERE NOMTABLE = 'AGENDA' AND PKEY = :KEY_VAL AND ID <> :ID; END ^ SET TERM ; ^
Partager