Exact Online raggiunge il limite giornaliero da Invantive Data Hub 26.0.X

Dalla versione 26.0.X di Data Hub, abbiamo riscontrato il raggiungimento del limite giornaliero delle chiamate API per un archivio Exact Online. In precedenza, non era questo il caso.

Attualmente stiamo analizzando dove si trova il problema: nel programma di aggiornamento, l’endpoint SalesOrderLines era ancora incluso con oltre 312k righe, il che rappresentava una causa logica di un elevato consumo. È stato temporaneamente rimosso dall’aggiornamento.

Tuttavia, continuiamo a incontrare il limite; di seguito una panoramica degli endpoint e una stima approssimativa del numero previsto di chiamate. Questo si traduce in un numero previsto di chiamate di circa 3.4k (considerando che probabilmente ci sono altre chiamate per token di aggiornamento ecc.).

In questo modo rimaniamo stimati sotto il limite di 5k al giorno, stiamo trascurando qualcosa che rende il numero di chiamate drasticamente superiore alla stima?

tabella tpn_count_rows Risultati per chiamata? Chiamate API necessarie?
ExactOnlineREST.PurchaseOrder.GoodsReceiptLines 20182 60 336
ExactOnlineREST.PurchaseOrder.GoodsReceipts 1750 60 29
ExactOnlineREST.Purchase.PurchaseInvoices 1038 60 17
ExactOnlineREST.Purchase.PurchaseInvoiceLines 20053 60 334
ExactOnlineREST.Logistics.ItemAssortments 10 60 0
ExactOnlineREST.Logistics.ItemAssortmentProperties 558 60 9
ExactOnlineREST.Financial.Journals 25 60 0
ExactOnlineREST.Financial.FinancialPeriods 72 60 1
ExactOnlineREST.Incremental.GLAccountsIncremental 830 1000 1
ExactOnlineREST.Incremental.TransactionLinesIncremental 492070 1000 492
ExactOnlineXML.XML.Items 8588 60 143
ExactOnlineREST.Logistics.ItemsBulk 8588 1000 9
ExactOnlineXML.XML.AROutstandingItems 427 60 7
ExactOnlineREST.Subscription.SubscriptionLineTypes 2 60 0
ExactOnlineREST.Subscription.SubscriptionLines 2 60 0
ExactOnlineREST.Subscription.Subscriptions 2 60 0
ExactOnlineREST.Subscription.SubscriptionTypes 4 60 0
ExactOnlineREST.HRM.Costunits 43 60 1
ExactOnlineREST.HRM.Costcenters 4 60 0
ExactOnlineREST.SalesInvoice.SalesInvoicesBulk 22474 1000 22
ExactOnlineREST.SalesInvoice.SalesInvoiceLinesBulk 326384 1000 326
ExactOnlineREST.SalesOrder.GoodsDeliveryLinesBulk 298456 1000 298
ExactOnlineREST.SalesOrder.GoodsDeliveriesBulk 35471 1000 35
ExactOnlineREST.SalesOrder.SalesOrders 27720 60 462
ExactOnlineREST.SalesOrder.SalesOrdersBulk 27720 1000 28
ExactOnlineREST.SalesOrder.SalesOrderLinesBulk 312594 1000 313
ExactOnlineREST.CRM.AccountClassifications 37 60 1
ExactOnlineREST.CRM.AddressesBulk 11560 1000 12
ExactOnlineREST.CRM.ContactsBulk 4415 1000 4
ExactOnlineREST.CRM.AccountsBulk 10330 1000 10
ExactOnlineREST.Logistics.SupplierItems 7989 60 133
ExactOnlineREST.PurchaseOrder.PurchaseOrders 1040 60 17
ExactOnlineREST.PurchaseOrder.PurchaseOrderLines 19986 60 333

Le chiamate API effettive si possono trovare nella schermata “Sessie-I/O’s” su Invantive Cloud. Qui sono incluse anche le misurazioni on-premise.

Il consiglio è di usarle per individuare i maggiori consumatori.

“Sessione-I/O” indicano i seguenti approfondimenti, filtrati sulla partizione dell’amministrazione dei problemi.

Panoramica del numero di I/O presenti raggruppati per “NomeTabella”.

Etichette di Righe Numero di Ordine di Smistamento
ExactOnlineREST.Incremental.TransactionLinesIncremental (new/modified) 999
ExactOnlineREST.SalesOrder.SalesOrders 926
ExactOnlineREST.PurchaseOrder.GoodsReceiptLines 674
ExactOnlineREST.Purchase.PurchaseInvoiceLines 670
ExactOnlineREST.SalesInvoice.SalesInvoiceLinesBulk 654
ExactOnlineREST.SalesOrder.SalesOrderLinesBulk 626
ExactOnlineREST.SalesOrder.GoodsDeliveryLinesBulk 598
ExactOnlineREST.PurchaseOrder.PurchaseOrderLines 317
ExactOnlineXML.XML.Items 172
ExactOnlineREST.SalesOrder.GoodsDeliveriesBulk 72
ExactOnlineREST.PurchaseOrder.GoodsReceipts 60
ExactOnlineREST.SalesOrder.SalesOrdersBulk 56
ExactOnlineREST.SalesInvoice.SalesInvoicesBulk 46
ExactOnlineREST.Purchase.PurchaseInvoices 36
ExactOnlineREST.Logistics.ItemAssortmentProperties 20
ExactOnlineREST.Logistics.ItemsBulk 18
ExactOnlineREST.Workflow.CustomerCooperations 12
ExactOnlineREST.Incremental.TransactionLinesIncremental/$count 6
ExactOnlineREST.Incremental.TransactionLinesIncremental (deleted) 4
ExactOnlineREST.Incremental.GLAccountsIncremental/$count 4
ExactOnlineREST.Incremental.TransactionLinesIncremental (metadata) 4
ExactOnlineREST.Financial.FinancialPeriods 4
ExactOnlineREST.Incremental.GLAccountsIncremental (new/modified) 2
ExactOnlineREST.Subscription.SubscriptionLineTypes 2
ExactOnlineREST.Logistics.ItemAssortments 2
ExactOnlineREST.Subscription.SubscriptionLines 2
ExactOnlineREST.Incremental.GLAccountsIncremental (metadata) 2
ExactOnlineREST.Subscription.Subscriptions 2
ExactOnlineREST.Incremental.GLAccountsIncremental (timemachine) 2
ExactOnlineREST.Financial.Journals 2
ExactOnlineXML.XML.AROutstandingItems 2
ExactOnlineREST.Incremental.GLAccountsIncremental (deleted) 2
ExactOnlineREST.HRM.Costcenters 2
ExactOnlineREST.Subscription.SubscriptionTypes 2
ExactOnlineREST.HRM.Costunits 2
Totale generale 6004

Cosa salta all’occhio:

ExactOnlineREST.Incremental.TransactionLinesIncremental (new/modified)

  • Questo valore è alto e non è atteso
  • Questo refresh viene avviato tramite la seguente istruzione:
select /*+ ods(true, interval ‘1 seconds’) */ count(*) 
from   ExactOnlineREST.Incremental.TransactionLinesIncremental@eolbe;
  • Questo rappresenta un problema per cui questo valore è così alto?

Tabelle bulk con un alto numero di chiamate

  • 654 chiamate su ExactOnlineREST.SalesInvoice.SalesInvoiceLinesBulk
  • Questa tabella ha in linea con la tabella iniziale circa 300k record.
  • Qui mi aspetterei dunque 300 chiamate, visto che una tabella bulk produce 1000 record per chiamata?

Il consiglio è di adeguare il numero di chiamate API al numero di righe. Questo può essere fatto rapidamente seguendo i suggerimenti su:

Un *Incremental normalmente effettuerà circa 1.000 chiamate API solo durante il caricamento iniziale o se c’è qualcosa che non va (ad esempio una deviazione troppo grande tra ciò che è in cache e il numero di righe).

Dalle 4 chiamate API in (deleted) si può leggere che quattro aggiornamenti completi hanno avuto luogo nel periodo misurato.

Questo può essere analizzato controllando negli I/O di Sessione quando e in quale ID di sessione le chiamate avvengono.

Qualcosa di simile vale per le tabelle *Bulk: nella schermata I/O di Sessione si trovano indizi per individuare quando ci sono stati aggiornamenti. Diversamente dalle *Incremental, ogni nuova azione di caricamento (ipotizzando 300K righe in SalesInvoiceLinesBulk) causerà circa 300 chiamate API. Se un secondo dopo la stessa query viene eseguita nuovamente, genererà di nuovo circa 300 chiamate API, e così via.

Questo può essere legato alle 4 chiamate API in (deleted). È possibile che uno script sia stato eseguito ripetutamente nel periodo misurato.

Lo script si avvia alle 07:30 CET tramite Utilità di pianificazione di Windows e crea un file di log, a livello di server posso trovare solo un file di log.

Gli I/O provengono tutti dall’esecuzione iniziata questa mattina e corrispondono agli orari con i registri:

Inizio:

2026-07-03 05:30:12.399 Information itgensql264: Invantive UniversalSQL statement started.

Stop:

2026-07-03 09:20:22.922 Error itgencun016: Errore itgeneor229: Non c'è più capacità giornaliera disponibile per l'uso dell'API di Exact Online nella divisione Exact Online ‘……’.
  Si prega di ottimizzare l'uso dell'API o contattare il Supporto di Exact Online per acquisire più chiamate API al giorno rispetto al limite attuale di 5.000 chiamate, oppure riprovare domani.

Il file con le query segue la seguente struttura:

use 123@eolbe;
SELECT /*+ ods(true, interval '1 seconds') */ count(*) FROM ExactOnlineREST.SalesOrder.SalesOrderLinesBulk@eolbe;
SELECT /*+ ods(true, interval '1 seconds') */ count(*) FROM ExactOnlineREST.SalesOrder.SalesOrdersBulk@eolbe;
... altre tabelle ...

use 456@eolbe;
SELECT /*+ ods(true, interval '1 seconds') */ count(*) FROM ExactOnlineREST.SalesOrder.SalesOrderLinesBulk@eolbe;
SELECT /*+ ods(true, interval '1 seconds') */ count(*) FROM ExactOnlineREST.SalesOrder.SalesOrdersBulk@eolbe;
... altre tabelle ...

use 789@eolbe;
SELECT /*+ ods(true, interval '1 seconds') */ count(*) FROM ExactOnlineREST.SalesOrder.SalesOrderLinesBulk@eolbe;
SELECT /*+ ods(true, interval '1 seconds') */ count(*) FROM ExactOnlineREST.SalesOrder.SalesOrdersBulk@eolbe;
... altre tabelle ...

Il consiglio è di collegare le informazioni dagli I/O sessioni con l’uso nei file di log, inclusi i timestamp.

Al momento non c’è motivo di presumere un bug.

È disponibile una procedura dettagliata per questo?

Non ho ancora chiaro il passo concreto che devo eseguire.

No, qui non c’è alcuna procedura o spiegazione dettagliata, né è previsto.

Il consiglio è di coinvolgere un consulente esperto o chiedere consigli tramite Claude AI.

La ricerca con Claude AI è stata effettuata con il seguente input:

  • I/O del 03/07/2026 sincronizzazione
  • Log del 03/07/2026 sincronizzazione (errore)
  • Log del 10/06/2026 sincronizzazione (riuscita, ancora su v24)

Ecco alcuni punti che potrebbero essere rilevanti:

Non 1000 record / chiamata

L'impronta della regressione è nei record per chiamata di luglio. Dall'esportazione I/O, ogni grande tabella di luglio restituisce quasi esattamente ~500 record per chiamata:

TransactionLines: 492.070 record / 999 chiamate = 492/chiamata
SalesOrderLinesBulk: 312.594 / 626 = 499/chiamata
SalesInvoiceLinesBulk: 326.384 / 654 = 499/chiamata
GoodsDeliveryLinesBulk: 298.456 / 598 = 499/chiamata

Gli endpoint di massa e di sincronizzazione di Exact Online restituiscono fino a 1.000 record per pagina. Ottenere un ~500 uniforme su quattro tabelle indipendenti non è una coincidenza — è una dimensione di pagina di 500, cioè pagine a metà grandezza, raddoppiando le chiamate per gli stessi dati. Applicando quel raddoppio a TransactionLines più le tre tabelle bulk si ottengono circa 1.800–1.900 chiamate che una pagina da 1.000 record avrebbe servito in ~950.

Intervallo ODS 1 secondo

Una tabella incrementale viene sempre aggiornata se si omette l’elemento “*/*+ ods(true, interval ‘1 seconds’) */”?

Attualmente, questo comporterebbe che si verifichi sempre una sincronizzazione completa?

Il consiglio è di collegare la relazione ai tempi; sembra trattarsi di più carichi. Exact Online conosce solo le dimensioni delle pagine prescritte esattamente da Exact.

Il suggerimento ods non influisce sulla logica per le tabelle incrementali o le cache HTTP; vedi anche:

Grazie per il feedback. Ho affiancato le I/O con il file di log come consigliato, e l’immagine di più carichi è confermata. Oggi il rinnovo sta rallentando e stiamo monitorando se questo attiverà nuovamente un limite.

Approfondimenti dall’IA:

Contesto: Data Hub 26.0.167. L’aggiornamento è avvenuto il 03/07 dalle 05:30 al crash alle 09:20:22 su itgeneor229 (“no daily capacity remaining … the current limit of 5 000 calls”). L’export delle I/O contiene 6.004 richieste, delle quali ~5.990 in questa singola finestra.

1. La dimensione della pagina è corretta. Per passaggio, Data Hub recupera ~999 righe/call (es. 312.594 righe / 313 chiamate), quindi la ~1.000 raccomandata da Exact. Il mio precedente “500/call” era un errore di conteggio: avevo diviso il numero di righe salvate per il numero totale di chiamate su due passaggi.

2. Ogni grande tabella viene recuperata due volte. Quando ordino le richieste per orario, ogni grande tabella si suddivide in due passaggi quasi identici con un’intervallo inattivo nel mezzo (0 chiamate durante l’intervallo), mentre il log registra solo un Downloaded … rows:

Tabella Passaggio 1 Passaggio 2 Log “Scaricato”
SalesOrderLinesBulk 05:34–05:45 (313 chiamate / 417 MB) 05:57–06:08 (313 chiamate / 421 MB) 312.594 righe (1×)
SalesInvoiceLinesBulk 07:27–07:34 (327 chiamate) 07:40–07:48 (327 chiamate) 326.384 righe (1×)
GoodsDeliveryLinesBulk 07:01–07:11 (299 chiamate) 07:17–07:26 (299 chiamate) 298.456 righe (1×)
TransactionLinesIncremental 08:22–08:25 (500 chiamate) 08:38–08:42 (499 chiamate) 492.070 righe (1×)
XML Items 07:54–07:57 (86 chiamate) 08:00–08:03 (86 chiamate) —

I due passaggi sono byte per byte simmetrici (es. 417 vs 421 MB per SalesOrderLinesBulk). I dati sono quindi salvati una volta, ma recuperati due volte.

3. Impatto sul limite giornaliero. I secondi passaggi sono in totale ~1.524 chiamate. Senza quella ripetizione, l’esecuzione sarebbe ~4.480 chiamate — sotto il limite di 5.000. Il superamento non è quindi dovuto alla dimensione della pagina o all’ancoraggio di sincronizzazione, ma al doppio recupero.

4. Confronto con un’esecuzione riuscita (09/06, Data Hub 24.0.445, stesso ods=1s): il log mostra lì un Downloaded … rows per tabella e l’esecuzione si è conclusa senza limite giornaliero, con volumi simili (o persino maggiori) su codice di divisione. Nota: quel log più vecchio non contiene I/O a livello di richiesta, quindi non posso contare esattamente le chiamate per giugno — il doppio recupero è visibile solo nell’export 26.0.167.

Domanda: potreste aiutarci a spiegare perché ogni tabella bulk/sync viene recuperata in due passaggi? Concretamente:

  • Il seeding ODS e il SELECT count(*) successivo attivano ciascuno un recupero separato?
  • A cosa attende l’esecuzione durante l’intervallo inattivo di ~6-12 minuti tra i due passaggi?

Sulla base delle informazioni disponibili, non c’è molto da dire.

Il consiglio è di:

Il tracciamento è attivo, suppongo che preferibilmente si tratti di un tracciamento che inizia dopo un reset del limite giornaliero?

Corretto, in modo che l’itgeneor229 non crei problemi per la completezza.

L’invio del file .zip risulta in un avviso di “Email non recapitata”

Il messaggio contiene 3 file “.zip” per un totale di soli 600kb

Il tracciamento è stato consegnato oggi.

Nota che questo aggiornamento è in corso nell’ambiente in cui è presente una seconda connessione con lo stesso nome del contenitore dati, il che potrebbe essere una conseguenza di: Viene scelta la connessione sbagliata nella release 26.0 di Invantive Data Hub - invantive?

I tre file sono stati analizzati. Queste tracce non contengono il ciclo di refresh stesso. Sono solo i primi file all’avvio del processo e coprono alcuni secondi.

Ciò che è notevole è che si tratta di tre processi separati che iniziano a pochi minuti l’uno dall’altro. Per il test è necessario far funzionare completamente il programma e poi ripetere. Considerando 5.000 chiamate API, ciò deve durare almeno 5.000 secondi.

Il consiglio è di raccogliere e inviare le tracce delle esecuzioni complete. È meglio farlo dopo un aggiornamento alla versione 26.0.169 che è ora disponibile come versione “corrente” su https://download.invantive.com.

L’aggiornamento alla versione 26.0.170 è stato previsto ed è ora in corso.

Le tre tracciature erano una simulazione limitata di una singola tabella, avviata tre volte di seguito.

Claude AI ha fornito il feedback che la tabella API sarebbe stata letta due volte di seguito a breve distanza, questo come nota a margine.

Non appena le tracciature con la nuova versione saranno completate, e se il problema persiste, verranno fornite le nuove tracce.

Da un’analisi interna è emersa una tendenza secondo cui il numero di chiamate API per AccountsIncremental (tabella clienti) è maggiore con la release 26.0 rispetto alla release 25.0 in un’amministrazione di prova su Exact Online.

In questa amministrazione ci sono circa 100.000 relazioni e una query legge AccountsIncremental 10-20 volte al giorno.

Release Numero di Chiamate al Giorno
25.0.190 220
25.0.205 391
25.0.210 112
25.0.211 145
26.0.011 2283
26.0.054 319
26.0.066 569
26.0.069 1091
26.0.148 1920
26.0.164 724
26.0.167 3690

Della recente release 26.0.167 è disponibile un traccia. Questa verrà utilizzata per un’analisi.

Il tracciamento dell’aggiornamento 26.0.170 è stato fornito tramite un link per il download al supporto Invantive.