Het synchronize
-statement is uitgebreid met opties om eigen logica uit te voeren die in Invantive PSQL is geschreven. De PSQL-logica wordt uitgevoerd wanneer een gebeurtenis wordt getriggerd (insert, update en/of delete). Aparte eigen triggerlogica kan worden gespecificeerd om te worden uitgevoerd voor en na de gebeurtenis, en in plaats van de gebeurtenis.
Het gebruik van eigen logica voor het triggeren van gebeurtenissen heeft de volgende voordelen in complexe datasynchronisatie- of data-integratiescenario’s, waardoor de bruikbaarheid als one-stop-integratieplatform voor bedrijfsgegevens toeneemt:
- vereenvoudigen data-integratie taken,
- verminderen hoeveelheid werk nodig is voor complexe synchronisatietaken
- verhogen de bruikbaarheid, controleerbaarheid en betrouwbaarheid.
De nieuwe functionaliteit is beschikbaar vanaf release 22.1 BETA en in de toekomstige productierelease.
Bestaande synchronisatiefunctionaliteit
De release 22.0 datasynchronisatiefunctionaliteit van synchronize
blijft volledig gehandhaafd en ondersteund.
Met synchronize
kan een enkel SQL-statement unidirectioneel of bidirectioneel de inhoud van twee tabellen vergelijken en gelijktrekken. Dit gelijktrekken door datasynchronisatie zorgt ervoor dat de waarden in de tabel voor identiek genaamde kolommen overeenkomen (rekening houdend met kleine verschillen in gegevensformaat zoals long
en short
). Voorbeelden voor datasynchronisatie zijn beschikbaar in:
- Synchroniseer uw gegevens met één SQL-statement over meerdere cloudplatformen heen
- Exact Online synchroniseren met Visma.net Financials
De functionaliteit van statements blijft behouden. Synchronize
blijft de voorkeursoplossing voor batchgewijze datasynchronisatie. Gebruik de andere Invantive SQL middelen voor real-time datasynchronisatie, zoals Invantive App Online voor het opvangen van webhookevents en uitvoeren van acties.
Uitdagingen voor datasynchronisatie
Het synchroniseren van gegevens is een krachtig concept voor data-integratie. Het datasynchronisatieproces kan echter extra eisen stellen boven de mogelijkheden van release 22.0, zoals verschillende tabellen om van te lezen en te schrijven, een optie voor dry-run en/of actie-auditing.
Verschillende tabellen om uit te lezen en te schrijven
Een typische uitdaging voor datasynchronisatietools is wanneer de tabel (of API) die moet worden aangepast anders is dan de tabel waarmee de gegevens worden vergeleken. Sommige platforms hebben bijvoorbeeld (relatief trage) tabellen die insert toestaan, maar waar de vergelijking gaat via een geoptimaliseerde read-only versie. Een populair voorbeeld hiervan zijn de Exact Online transactietabellen; terwijl de (alleen-lezen) *Incremental
tabellen gemakkelijk grote datavolumes zoals miljoenen transacties in minuten teruggeven, maar waarbij de lees/schrijf-versie beperkt is tot maximaal 60 rijen per seconde en een cumulatief leesgebruik van maximaal 300.000 rijen per dag.
Met behulp van aangepaste logica voor het triggeren van gebeurtenissen, kan de synchronisatie lezen uit een incrementele tabel zoals AccountsIncremental
en wijzigingen aanbrengen via de (langzamere) Accounts
-tabel. Dit zal tot honderden keren sneller lopen, terwijl het de belasting vermindert en de schaalbaarheid in grote omgevingen beter wordt.
Natuurlijk is in dit scenario aangenomen dat beide tabellen na verloop van tijd steeds meer identieke gegevens bevatten (en natuurlijk dezelfde gegevens direct na afloop van de synchronisatie). De vermindering van het aantal benodigde wijzigingen vermindert de geamortiseerde looptijd aanzienlijk door de aangepaste logica.
Dry-run en actie-auditing
Een andere uitdaging voor synchronisatietools voor bedrijfsgegevens is dat de synchronisatie prima verloopt, maar dat het door de complexiteit van het synchronisatieproces moeilijk is om het eigenlijke proces te controleren. Of erger nog, soms moet de lijst met wijzigingen worden afgetekend voordat de eigenlijke synchronisatie kan plaatsvinden.
Door aangepaste code te gebruiken om gegevens te synchroniseren kunnen de wijzigingen vooraf worden getoond en kan gemakkelijk een audittrail van de feitelijke wijzigingen worden vastgelegd, zelfs wanneer het doelplatform geen auditfuncties heeft.
Voorbeeld van aangepaste logica
Het synchronize
-statement synchroniseert de brontabel met de doeltabel via eigen logica voor alle triggers. Er zijn negen mogelijke triggers op een synchronisatie, namelijk elke combinatie van:
- gebeurtenis: insert, update en delete,
- uitvoeringsmoment voor, in plaats van en na de gebeurtenis.
Aan het einde van het synchronize
-statement worden na het sleutelwoord triggers
de triggers gespecificeerd als het uitvoeringsmoment en de gebeurtenis. Bijvoorbeeld, de volgende logica wordt uitgevoerd voorafgaand een insert:
synchronize
...
triggers
before insert
begin
... code ...
end;
De PSQL-code kan verwijzen naar de oude en nieuwe waardes via, respectievelijk, het voorvoegsel :old
en :new
. Merk op dat :old
en :new
afhankelijk zijn van de synchronisatierichting. In het bijzonder voor bidirectionele synchronisatie kunnen de bron- en doel-tabel telkens weer anders zijn. Kolommen niet beschikbaar in de geselecteerde bron of doel met :old
en :new
verwijzingen evalueren naar null
.
Wanneer een tabel bijvoorbeeld de kolom name
bevat, zal de volgende code wijzigingen van de naam afdrukken:
synchronize
...
triggers
before update
begin
if ( :old.name is null and :new.name is not null )
or
( :old.name is not null and :new.name is null )
or
:old.name != :new.name
then
dbms_output.put_line('Name is changed from ' || :old.name || ' to ' || :new.name || '.');
end if;
end;
Voorbeeld van eigen logica
Het onderstaande voorbeeld synchroniseert de bron- naar de doeltabel met behulp van triggers. Maak en vul de tabellen eerst zoals getoond aan het einde van dit artikel voordat u gegevens synchroniseert.
Het resultaat van de uitvoering in dit geval is altijd:
voor insert met ID A
in plaats van insert met ID A: 5
na insert met ID A
voor update met ID B
in plaats van update met ID B: 4 → 7
na update met ID B
Datasynchronisatiestatement:
sync source@inmemorystorage
to target@inmemorystorage
with insert or update or delete
identified
by dummy_string
triggers
before insert
begin
dbms_output.put_line('before insert on ID ' || :new.dummy_string);
end
instead of insert
begin
dbms_output.put_line('instead of insert on ID ' || :new.dummy_string || ': ' || :new.dummy_int32);
end
after insert
begin
dbms_output.put_line('after insert on ID ' || :new.dummy_string);
end
before update
begin
dbms_output.put_line('before update on ID ' || :new.dummy_string);
end
instead of update
begin
dbms_output.put_line('instead of update on ID ' || :new.dummy_string || ': ' || :old.dummy_int32 || ' -> ' || :new.dummy_int32);
end
after update
begin
dbms_output.put_line('after update on ID ' || :new.dummy_string);
end
before delete
begin
dbms_output.put_line('before delete on ID ' || :old.dummy_string);
end
instead of delete
begin
dbms_output.put_line('instead of delete on ID ' || :old.dummy_string);
end
after delete
begin
dbms_output.put_line('after delete on ID ' || :old.dummy_string);
end
Voorbeeld tabelcreatie
Gelieve ter voorbereiding op de synchronisatie met de volgende SQL-code twee tabellen aan te maken (source
en target
) met de volgende inhoud.
Tabel source
dummy_string | dummy_int32 | dummy_datetime |
---|---|---|
A | 5 | now |
B | 7 | now |
C | 9 | now |
Tabel Target
dummy_string | dummy_int32 |
---|---|
B | 4 |
C | 9 |
Code voor Tabellen
create or replace table source@inmemorystorage
as
select 5 dummy_int32
, now() dummy_datetime
, 'A' dummy_string
union all
select 7 dummy_int32
, now() dummy_datetime
, 'B' dummy_string
union all
select 9 dummy_int32
, now() dummy_datetime
, 'C' dummy_string
create or replace table target@inmemorystorage
as
select 'B' dummy_string
, 4 dummy_int32
union all
select 'C' dummy_string
, 9 dummy_int32
Bulk laden
In het algemeen worden de triggers met aangepaste logica per rij aangeroepen, dus als er twee rijen moeten worden bijgewerkt, is de volgorde van aanroepen:
- voor update rij 1
- (in plaats van) update rij 1
- na update rij 1
- voor update rij 2
- (in plaats van) update rij 2
- na update rij 2
Invantive SQL biedt echter ondersteuning voor bulkladen op verschillende platformen zoals SQL Server, PostgreSQL en Oracle RDBMS (native driver). In dat geval worden inserts gebundeld in batches. De grootte van elke batch kan worden gespecificeerd met het batchsize
sleutelwoord (documentatie).
Elke batch wordt typisch verwerkt als een ondeelbare eenheid, maar het hoeft geen atomaire transactie te zijn. Bij mislukking zullen één of meer rijen in de batch niet geladen worden en andere wel. In het algemeen is het onmogelijk te achterhalen welke rijen mislukt en/of geldig zijn zonder de uiteindelijke database-inhoud opnieuw te lezen.
Bij geen gebruik van een in plaats van-trigger en bulkladen met een batchgrootte groter dan 1, zal de aanroepvolgorde voor twee rijen die worden ingevoegd zijn:
- voor insert rij 1
- voor insert rij 2
- bulk insert rij 1 en 2
- na insert rij 1
- na insert rij 2
Wanneer er meer rijen te laden zijn dan de batchgrootte toelaat, zal de aanroepvolgorde dezelfde zijn, maar alleen voor de rijen in een batch. Latere batches zullen de volgorde vanaf het begin herhalen met andere rijen.