web-dev-qa-db-fra.com

Oracle 10G: Utiliser correctement ora_rowscn pour détecter les modifications de la ligne de table (c.-à-d. Inserts, mises à jour, suppression)

Certaines recherches sur la vérification lorsque les enregistrements d'un tableau ont été mis à jour, modifiés ou supprimés me sont amenés à la colonne pseudo connue sous le nom d'ora_rowscn.

Tout d'abord, je fais ça:

select max(ora_rowscn) from tablename;

Je prends note du nombre. Ensuite, je fais un insertion, une mise à jour et une suppression, vérifiez que la valeur maximale avant et après chacune. Il semble augmenter pour chaque type de changement.

Si vous vous demandez pourquoi je fais cela, nous mettons en cache une liste d'entités dans notre service Windows C #. Ce service fonctionne sur deux serveurs à charge équilibrée de la charge. Il existe donc une instance séparée de chaque courant. Lorsqu'une mise à jour survient sur le serveur A, Server B a besoin de savoir à ce sujet. Ce que je veux faire, c'est cache max (ora_rowscn) dans une variable. Chaque fois que notre application va à insérer, à mettre à jour ou à supprimer un enregistrement, elle obtiendra un nouveau Max dans la base de données. Si la valeur est différente, elle sait évidemment qu'il doit aller obtenir une nouvelle liste de la base de données.

Donc, ma question actuelle est la suivante: y a-t-il d'autres accrocheurs que je devrais être au courant de cela pourrait entraîner une insertion, une mise à jour ou une suppression d'un enregistrement ne pas incrémenter cette valeur?

Edit : Peut-il ajouter ora_rowscn comme une étiquette?

6
oscilatingcretin

Obtenir le max (ORA_ROWSCN) nécessitera une numérisation de table complète à chaque fois que vous le faites. Cela peut être plus rapide juste pour rafraîchir la cache entière à chaque fois.

On dirait que vous avez besoin d'un moyen d'informer l'autre service qu'un changement a eu lieu et de ce que le changement était. Vous pouvez maintenir une table de journaux avec une colonne indiquant quel système doit consommer le changement. La colonne pourrait avoir deux index basés sur la fonction une pour chaque service afin que chaque index ne contienne que les entrées à consommer. Ensuite, comme ils sont consommés, ils peuvent rendre la valeur null pour le supprimer de l'index.

Ou vous pouvez simplement utiliser Oracle - Queue avancée .

6
Leigh Riffel

Comme @leigh Riffel a noté, un Select Max (ORA_ROWSCN) entraînera une analyse de la table complète. Une alternative consiste à avoir une colonne d'horodatage (nous appellerons SYS_TS pour cet exemple) peuplé au moment de l'exécution de l'instruction (qui n'est pas identique à l'engagement de la déclaration, qui est lorsque le SCN est généré/peuplé). Un index sur la colonne SYS_TS vous permettra de regarder les dernières lignes X (disons 25) pour trouver le max ora_rowscn uniquement à partir de ces lignes.

Le moyen le plus simple de le faire serait d'utiliser le rownum pour limiter les résultats tels que décrits dans cet article [1] Demander à Tom Article:

select *
from (select sys_ts, ora_rowscn
from table order by SYS_TS desc) where rownum < 25;

Malheureusement, cela entraîne également une analyse de table complète (au moins dans Oracle 11.2.0.3). Cela a été signalé à Oracle, mais déterminé à ne pas être un défaut (bogue 17347125).

Cela nécessite un peu plus de travail pour atteindre efficacement le même résultat:

select b.sys_ts,b.ora_rowscn from
    (select rid from 
        (select rowid as rid from table order by sys_ts desc) 
    where rownum <= 25) a, table b
where a.rid = b.rowid;

[1] - http://www.oracle.com/techNetwork/issue-archive/2006/06-ep/o56Osktom-086197.html

2
Brett Okken