Una transazione è un'operazione o un insieme di operazioni che hanno la garanzia di essere atomiche, il che significa che le transazioni non vengono mai applicate parzialmente. Vengono applicate tutte le operazioni della transazione o nessuna. Le transazioni hanno una durata massima di 60 secondi con un tempo di scadenza di inattività di 10 secondi dopo 30 secondi.
Utilizzando l'API asincrona NDB,
un'applicazione può gestire più
transazioni contemporaneamente se sono indipendenti.
L'API sincrona offre un'API semplificata utilizzando il
@ndb.transactional() decoratore.
La funzione decorata viene eseguita nel contesto della transazione.
Se la transazione "entra in conflitto" con un'altra, non va a buon fine. NDB ritenta automaticamente
le transazioni non riuscite alcune volte.
La funzione può essere chiamata più volte se la transazione
viene ritentata. Esiste un limite (valore predefinito 3) al numero di tentativi
Se la transazione non va ancora a buon fine, NDB
genera TransactionFailedError. Puoi modificare il numero di tentativi passando retries=N al
transactional() decoratore.
Un numero di tentativi pari a 0 significa che la transazione
viene tentata una volta, ma non viene ritentata se non va a buon fine. Un numero di tentativi pari a
N significa che la transazione può essere tentata un totale di
N+1 volte. Esempio:
Nelle transazioni sono consentite solo le query di antenati. Per impostazione predefinita, una transazione può funzionare solo con le entità dello stesso gruppo di entità (entità le cui chiavi hanno lo stesso "predecessore").
Puoi specificare le transazioni tra gruppi ("XG") (che consentono fino a 25 gruppi di entità) passando
xg=True:
Le transazioni tra gruppi operano su più gruppi di entità e si comportano come transazioni a gruppo singolo, ma non vanno a buon fine se il codice tenta di aggiornare le entità da più di un gruppo di entità.
Se la funzione genera un'eccezione,
la transazione viene immediatamente interrotta e NDB genera di nuovo l'
eccezione in modo che il codice chiamante la veda.
Puoi forzare l'esito negativo di una transazione senza generare errori generando l'
ndb.Rollback eccezione (in questo caso la
chiamata di funzione restituisce None
). Non esiste un meccanismo per forzare un tentativo.
Potresti avere una funzione che non vuoi sempre eseguire in una transazione. Invece di decorare una funzione di questo tipo
con @ndb.transactional, passala come funzione di callback
a ndb.transaction()
Per verificare se un codice è in esecuzione all'interno di una transazione,
utilizza la
in_transaction()
funzione.
Puoi specificare il comportamento di una funzione "transazionale" se viene richiamata
da un codice già in una transazione. Il
@ndb.non_transactional decoratore specifica che una funzione
non deve essere eseguita in una transazione. Se viene chiamata in una transazione, viene eseguita
al di fuori della transazione. Il @ndb.transactional decoratore
e la ndb.transaction funzione accettano un propagation argomento parola chiave. Ad esempio, se una funzione
deve avviare una nuova transazione indipendente, decorala nel seguente modo:
I tipi di propagazione sono elencati con le altre opzioni di contesto e opzioni di transazione
Il comportamento delle transazioni e il comportamento di memorizzazione nella cache di NDB possono confondere se non sai cosa sta succedendo. Se modifichi un'entità all'interno di una transazione, ma non hai ancora eseguito il commit della transazione, la cache di contesto di NDB contiene il valore modificato, ma il datastore sottostante contiene ancora il valore non modificato.
Accodamento delle attività transazionali
Puoi accodare un'attività come parte di una transazione Datastore, in modo che l'attività venga accodata solo se il commit della transazione viene eseguito correttamente. Se il commit della transazione non viene eseguito, l'attività non viene accodata. Se il commit della transazione viene eseguito, l'attività viene accodata. Una volta accodata, l'attività non verrà eseguita immediatamente, quindi non è atomica con la transazione. Tuttavia, una volta accodata, l'attività verrà ritentata finché non va a buon fine. Questo vale per qualsiasi attività accodata durante una funzione decorata.
Le attività transazionali sono utili perché ti consentono di combinare azioni non Datastore a una transazione che dipende dal successo della transazione (ad esempio, l'invio di un'email di conferma di un acquisto). Puoi anche collegare le azioni Datastore alla transazione, ad esempio per eseguire il commit delle modifiche ai gruppi di entità al di fuori della transazione se e solo se la transazione va a buon fine.
Un'applicazione non può inserire più di cinque attività transazionali nelle code di attività durante una singola transazione. Le attività transazionali non devono avere nomi specificati dall'utente.