Transazioni

Una transazione è un insieme di operazioni su una o più entità. Ogni transazione è garantita come atomica, il che significa che le transazioni non vengono mai applicate parzialmente. Vengono applicate tutte le operazioni nella transazione oppure nessuna.

Utilizzo delle transazioni

Le transazioni scadono dopo 270 secondi o se sono inattive per 60 secondi.

Un'operazione può non riuscire quando:

  • Sono stati tentati troppi aggiornamenti simultanei sulla stessa entità.
  • La transazione supera un limite di risorse.
  • Il database in modalità Datastore rileva un errore interno.

In tutti questi casi, l'API Datastore restituisce un errore.

Le transazioni sono una funzionalità facoltativa. Non è necessario utilizzare le transazioni per eseguire operazioni sul database.

Un'applicazione può eseguire un insieme di istruzioni e operazioni in un'unica transazione, in modo che se un'istruzione o un'operazione genera un'eccezione, nessuna delle operazioni del database nel set venga applicata. L'applicazione definisce le azioni da eseguire nella transazione.

Il seguente snippet mostra come eseguire una transazione. Trasferisce denaro da un conto all'altro.

C#

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore C#.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

private void TransferFunds(Key fromKey, Key toKey, long amount)
{
    using (var transaction = _db.BeginTransaction())
    {
        var entities = transaction.Lookup(fromKey, toKey);
        entities[0]["balance"].IntegerValue -= amount;
        entities[1]["balance"].IntegerValue += amount;
        transaction.Update(entities);
        transaction.Commit();
    }
}

Go

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Go.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

type BankAccount struct {
	Balance int
}

const amount = 50
keys := []*datastore.Key{to, from}
tx, err := client.NewTransaction(ctx)
if err != nil {
	log.Fatalf("client.NewTransaction: %v", err)
}
accs := make([]BankAccount, 2)
if err := tx.GetMulti(keys, accs); err != nil {
	tx.Rollback()
	log.Fatalf("tx.GetMulti: %v", err)
}
accs[0].Balance += amount
accs[1].Balance -= amount
if _, err := tx.PutMulti(keys, accs); err != nil {
	tx.Rollback()
	log.Fatalf("tx.PutMulti: %v", err)
}
if _, err = tx.Commit(); err != nil {
	log.Fatalf("tx.Commit: %v", err)
}

Java

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Java.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

void transferFunds(Key fromKey, Key toKey, long amount) {
  Transaction txn = datastore.newTransaction();
  try {
    List<Entity> entities = txn.fetch(fromKey, toKey);
    Entity from = entities.get(0);
    Entity updatedFrom =
        Entity.newBuilder(from).set("balance", from.getLong("balance") - amount).build();
    Entity to = entities.get(1);
    Entity updatedTo =
        Entity.newBuilder(to).set("balance", to.getLong("balance") + amount).build();
    txn.put(updatedFrom, updatedTo);
    txn.commit();
  } finally {
    if (txn.isActive()) {
      txn.rollback();
    }
  }
}

Node.js

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Node.js.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

async function transferFunds(fromKey, toKey, amount) {
  const transaction = datastore.transaction();
  await transaction.run();
  const results = await Promise.all([
    transaction.get(fromKey),
    transaction.get(toKey),
  ]);
  const accounts = results.map(result => result[0]);

  accounts[0].balance -= amount;
  accounts[1].balance += amount;

  transaction.save([
    {
      key: fromKey,
      data: accounts[0],
    },
    {
      key: toKey,
      data: accounts[1],
    },
  ]);

  return await transaction.commit();
}

PHP

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore PHP.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

/**
 * Update two entities in a transaction.
 *
 * @param string $fromKeyId
 * @param string $toKeyId
 * @param int $amount
 * @param string $namespaceId
 */
function transfer_funds(
    string $fromKeyId,
    string $toKeyId,
    int $amount,
    string $namespaceId = null
) {
    $datastore = new DatastoreClient(['namespaceId' => $namespaceId]);
    $transaction = $datastore->transaction();
    $fromKey = $datastore->key('Account', $fromKeyId);
    $toKey = $datastore->key('Account', $toKeyId);
    // The option 'sort' is important here, otherwise the order of the result
    // might be different from the order of the keys.
    $result = $transaction->lookupBatch([$fromKey, $toKey], ['sort' => true]);
    if (count($result['found']) != 2) {
        $transaction->rollback();
    }
    $fromAccount = $result['found'][0];
    $toAccount = $result['found'][1];
    $fromAccount['balance'] -= $amount;
    $toAccount['balance'] += $amount;
    $transaction->updateBatch([$fromAccount, $toAccount]);
    $transaction->commit();
}

Python

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Python.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

def transfer_funds(client, from_key, to_key, amount):
    with client.transaction():
        from_account = client.get(from_key)
        to_account = client.get(to_key)

        from_account["balance"] -= amount
        to_account["balance"] += amount

        client.put_multi([from_account, to_account])

Ruby

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Ruby.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

def transfer_funds from_key, to_key, amount
  datastore.transaction do |tx|
    from = tx.find from_key
    from["balance"] -= amount
    to = tx.find to_key
    to["balance"] += amount
    tx.save from, to
  end
end

Tieni presente che, per rendere gli esempi più concisi, a volte omettiamo rollback se la transazione non va a buon fine. Nel codice di produzione, è importante assicurarsi che ogni transazione venga eseguita o annullata in modo esplicito.

Cosa si può fare in una transazione

Le transazioni possono eseguire query o ricerche su qualsiasi numero di entità. La dimensione massima di una transazione è 10 MiB. Puoi utilizzare una transazione di lettura/scrittura o una transazione di sola lettura.

Isolamento e coerenza

I database in modalità Datastore applicano l'isolamento serializzabile. I dati letti o modificati da una transazione non possono essere modificati contemporaneamente.

Le query e le ricerche in una transazione visualizzano uno snapshot coerente dello stato del database. Questo snapshot contiene sicuramente l'effetto di tutte le transazioni e le scritture completate prima dell'inizio della transazione.

Questa visualizzazione coerente dello snapshot si estende anche alle letture dopo le scritture all'interno delle transazioni. A differenza della maggior parte dei database, le query e le ricerche all'interno di una transazione in modalità Datastore non vedono i risultati delle scritture precedenti all'interno della transazione. Nello specifico, se un'entità viene modificata o eliminata all'interno di una transazione, una query o una ricerca restituisce la versione originale dell'entità all'inizio della transazione oppure nulla se l'entità non esisteva in quel momento.

Al di fuori delle transazioni, anche le query e le ricerche hanno un isolamento serializzabile.

Modalità di concorrenza

Firestore in modalità Datastore supporta tre modalità di concorrenza. La modalità di concorrenza è un'impostazione del database che determina il modo in cui interagiscono le transazioni simultanee. Puoi scegliere una delle seguenti modalità di concorrenza:

  • Pessimista

    Le transazioni di lettura/scrittura utilizzano blocchi di lettura/scrittura per applicare l'isolamento e la serializzabilità. Quando due o più transazioni di lettura/scrittura simultanee leggono o scrivono gli stessi dati, il blocco mantenuto da una transazione può ritardare le altre transazioni. Se la transazione non richiede scritture, puoi migliorare le prestazioni ed evitare conflitti con altre transazioni utilizzando una transazione di sola lettura. Le transazioni di sola lettura non richiedono blocchi.

    I database Firestore in modalità Datastore utilizzano la modalità di concorrenza pessimistica per impostazione predefinita.

  • Ottimista

    Quando due o più transazioni di lettura/scrittura simultanee leggono o scrivono gli stessi dati, solo la prima transazione che esegue il commit delle modifiche ha esito positivo. Altre transazioni che eseguono scritture non vanno a buon fine al commit.

  • Ottimista con i gruppi di entità

    Utilizza questa modalità di concorrenza solo se la tua app dipende dalla semantica transazionale dei gruppi di entità di Cloud Datastore legacy. Questa modalità di concorrenza impone limiti aggiuntivi alle transazioni:

    • Le transazioni sono limitate a 25 gruppi di entità.
    • Le scritture a un gruppo di entità sono limitate a 1 al secondo.
    • Le query nelle transazioni devono essere query principali.

    Per rimuovere le limitazioni di query, transazioni e velocità effettiva di scrittura di OPTIMISTIC_WITH_ENTITY_GROUPS, imposta la modalità di concorrenza del progetto su Ottimistica. Per assicurarti che questa modifica sia compatibile con il tuo progetto:

    1. Crea un progetto di test in Firestore in modalità Datastore.

    2. Modifica la modalità di concorrenza del progetto di test in OPTIMISTIC. Emetti una richiesta HTTP PATCH, come mostrato di seguito.

    3. Esegui test sul progetto di test per assicurarti che il carico di lavoro venga eseguito come previsto senza i gruppi di entità.

    4. Modifica la modalità di concorrenza del progetto principale da OPTIMISTIC_WITH_ENTITY_GROUPS a OPTIMISTIC.

Visualizzare la modalità di concorrenza

Utilizza la risorsa REST Firestore projects.databases per visualizzare la modalità di concorrenza del database:

curl -X GET -H "Authorization: Bearer "$(gcloud auth print-access-token) \
"https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases"

Modificare la modalità di concorrenza

Per modificare la modalità di concorrenza del database, invia una richiesta PATCH alla risorsa REST projects.databases di Firestore:

curl --request PATCH \
--header "Authorization: Bearer "$(gcloud auth print-access-token) \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{"concurrencyMode":"CONCURRENCY_MODE"}' \
"https://firestore.googleapis.com/v1/projects/PROJECT_ID/databases/(default)?updateMask=concurrencyMode"

dove:

  • CONCURRENCY_MODE è PESSIMISTIC, OPTIMISTIC o OPTIMISTIC_WITH_ENTITY_GROUPS.
  • PROJECT_ID è l'ID del tuo progetto Google Cloud .

Utilizzi per le transazioni

Un utilizzo delle transazioni è l'aggiornamento di un'entità con un nuovo valore della proprietà relativo al suo valore attuale. L'esempio transferFunds riportato sopra lo fa per due entità, prelevando denaro da un conto e trasferendolo a un altro. L'API Datastore non ripete automaticamente le transazioni, ma puoi aggiungere la tua logica per riprovarle, ad esempio per gestire i conflitti quando un'altra richiesta aggiorna la stessa entità contemporaneamente.

C#

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore C#.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

/// <summary>
/// Retry the action when a Grpc.Core.RpcException is thrown.
/// </summary>
private T RetryRpc<T>(Func<T> action)
{
    List<Grpc.Core.RpcException> exceptions = null;
    var delayMs = _retryDelayMs;
    for (int tryCount = 0; tryCount < _retryCount; ++tryCount)
    {
        try
        {
            return action();
        }
        catch (Grpc.Core.RpcException e)
        {
            if (exceptions == null)
                exceptions = new List<Grpc.Core.RpcException>();
            exceptions.Add(e);
        }
        System.Threading.Thread.Sleep(delayMs);
        delayMs *= 2;  // Exponential back-off.
    }
    throw new AggregateException(exceptions);
}

private void RetryRpc(Action action)
{
    RetryRpc(() => { action(); return 0; });
}

[Fact]
public void TestTransactionalRetry()
{
    int tryCount = 0;
    var keys = UpsertBalances();
    RetryRpc(() =>
    {
        using (var transaction = _db.BeginTransaction())
        {
            TransferFunds(keys[0], keys[1], 10, transaction);
            // Insert a conflicting transaction on the first try.
            if (tryCount++ == 0)
                TransferFunds(keys[1], keys[0], 5);
            transaction.Commit();
        }
    });
    Assert.Equal(2, tryCount);
}

Go

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Go.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

type BankAccount struct {
	Balance int
}

const amount = 50
_, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
	keys := []*datastore.Key{to, from}
	accs := make([]BankAccount, 2)
	if err := tx.GetMulti(keys, accs); err != nil {
		return err
	}
	accs[0].Balance += amount
	accs[1].Balance -= amount
	_, err := tx.PutMulti(keys, accs)
	return err
})

Java

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Java.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

int retries = 5;
while (true) {
  try {
    transferFunds(fromKey, toKey, 10);
    break;
  } catch (DatastoreException e) {
    if (retries == 0) {
      throw e;
    }
    --retries;
  }
}
// Retry handling can also be configured and automatically applied using google-cloud-java.

Node.js

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Node.js.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

async function transferFundsWithRetry() {
  const maxTries = 5;

  async function tryRequest(currentAttempt, delay) {
    try {
      await transferFunds(fromKey, toKey, 10);
    } catch (err) {
      if (currentAttempt <= maxTries) {
        // Use exponential backoff
        setTimeout(async () => {
          await tryRequest(currentAttempt + 1, delay * 2);
        }, delay);
      }
      throw err;
    }
  }

  await tryRequest(1, 100);
}

PHP

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore PHP.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

$retries = 5;
for ($i = 0; $i < $retries; $i++) {
    try {
        require_once __DIR__ . '/transfer_funds.php';
        transfer_funds($fromKeyId, $toKeyId, 10, $namespaceId);
    } catch (\Google\Cloud\Core\Exception\ConflictException $e) {
        // if $i >= $retries, the failure is final
        continue;
    }
    // Succeeded!
    break;
}

Python

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Python.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

import google.cloud.exceptions

for _ in range(5):
    try:
        transfer_funds(client, account1.key, account2.key, 50)
        break
    except google.cloud.exceptions.Conflict:
        continue
else:
    print("Transaction failed.")

Ruby

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Ruby.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

(1..5).each do |i|
  begin
    return transfer_funds from_key, to_key, amount
  rescue Google::Cloud::Error => e
    raise e if i == 5
  end
end

Ciò richiede una transazione perché il valore di balance in un'entità potrebbe essere aggiornato da un altro utente dopo che questo codice recupera l'oggetto, ma prima che lo salvi. Senza una transazione, la richiesta dell'utente utilizza il valore di balance precedente all'aggiornamento dell'altro utente e il salvataggio sovrascrive il nuovo valore. Con una transazione, l'applicazione viene informata dell'aggiornamento dell'altro utente.

Un altro utilizzo comune delle transazioni è recuperare un'entità con una chiave denominata o crearla se non esiste ancora (questo esempio si basa sull'esempio TaskList della creazione di un'entità):

C#

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore C#.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

Entity task;
using (var transaction = _db.BeginTransaction())
{
    task = transaction.Lookup(_sampleTask.Key);
    if (task == null)
    {
        transaction.Insert(_sampleTask);
        transaction.Commit();
    }
}

Go

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Go.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

_, err := client.RunInTransaction(ctx, func(tx *datastore.Transaction) error {
	var task Task
	if err := tx.Get(key, &task); err != datastore.ErrNoSuchEntity {
		return err
	}
	_, err := tx.Put(key, &Task{
		Category:    "Personal",
		Done:        false,
		Priority:    4,
		Description: "Learn Cloud Datastore",
	})
	return err
})

Java

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Java.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

Entity task;
Transaction txn = datastore.newTransaction();
try {
  task = txn.get(taskKey);
  if (task == null) {
    task = Entity.newBuilder(taskKey).build();
    txn.put(task);
    txn.commit();
  }
} finally {
  if (txn.isActive()) {
    txn.rollback();
  }
}

Node.js

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Node.js.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

async function getOrCreate(taskKey, taskData) {
  const taskEntity = {
    key: taskKey,
    data: taskData,
  };
  const transaction = datastore.transaction();

  try {
    await transaction.run();
    const [task] = await transaction.get(taskKey);
    if (task) {
      // The task entity already exists.
      await transaction.rollback();
    } else {
      // Create the task entity.
      transaction.save(taskEntity);
      await transaction.commit();
    }
    return taskEntity;
  } catch (err) {
    await transaction.rollback();
  }
}

PHP

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore PHP.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

$transaction = $datastore->transaction();
$entity = $transaction->lookup($task->key());
if ($entity === null) {
    $entity = $transaction->insert($task);
    $transaction->commit();
}

Python

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Python.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

import datetime

with client.transaction():
    key = client.key(
        "Task", datetime.datetime.now(tz=datetime.timezone.utc).isoformat()
    )

    task = client.get(key)

    if not task:
        task = datastore.Entity(key)
        task.update({"description": "Example task"})
        client.put(task)

    return task

Ruby

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Ruby.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

task = nil
datastore.transaction do |tx|
  task = tx.find task_key
  if task.nil?
    task = datastore.entity task_key do |t|
      t["category"] = "Personal"
      t["done"] = false
      t["priority"] = 4
      t["description"] = "Learn Cloud Datastore"
    end
    tx.save task
  end
end

Come in precedenza, è necessaria una transazione per gestire il caso in cui un altro utente tenti di creare o aggiornare un'entità con lo stesso ID stringa. Senza una transazione, se l'entità non esiste e due utenti tentano di crearla, il secondo sovrascrive il primo senza saperlo.

Quando una transazione non va a buon fine, puoi fare in modo che la tua app riprovi la transazione finché non va a buon fine oppure puoi lasciare che gli utenti gestiscano l'errore propagandolo al livello dell'interfaccia utente della tua app. Non devi creare un ciclo di nuovi tentativi per ogni transazione.

Transazioni di sola lettura

Infine, puoi utilizzare una transazione per leggere uno snapshot coerente del database. Questa opzione può essere utile quando sono necessarie più letture per il rendering di una pagina o per esportare dati che devono essere coerenti. Puoi creare una transazione di sola lettura per questi casi.

Le transazioni di sola lettura non possono modificare le entità, ma in cambio non entrano in conflitto con altre transazioni e non devono essere riprovate. Se esegui solo letture in una normale transazione di lettura/scrittura, questa transazione potrebbe entrare in conflitto con le transazioni che modificano gli stessi dati.

C#

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore C#.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

Entity taskList;
IReadOnlyList<Entity> tasks;
using (var transaction = _db.BeginTransaction(TransactionOptions.CreateReadOnly()))
{
    taskList = transaction.Lookup(taskListKey);
    var query = new Query("Task")
    {
        Filter = Filter.HasAncestor(taskListKey)
    };
    tasks = transaction.RunQuery(query).Entities;
    transaction.Commit();
}

Go

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Go.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

tx, err := client.NewTransaction(ctx, datastore.ReadOnly)
if err != nil {
	log.Fatalf("client.NewTransaction: %v", err)
}
defer tx.Rollback() // Transaction only used for read.

ancestor := datastore.NameKey("TaskList", "default", nil)
query := datastore.NewQuery("Task").Ancestor(ancestor).Transaction(tx)
var tasks []Task
_, err = client.GetAll(ctx, query, &tasks)

Java

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Java.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

Entity taskList;
QueryResults<Entity> tasks;
Transaction txn =
    datastore.newTransaction(
        TransactionOptions.newBuilder().setReadOnly(ReadOnly.newBuilder().build()).build());
try {
  taskList = txn.get(taskListKey);
  Query<Entity> query =
      Query.newEntityQueryBuilder()
          .setKind("Task")
          .setFilter(PropertyFilter.hasAncestor(taskListKey))
          .build();
  tasks = txn.run(query);
  txn.commit();
} finally {
  if (txn.isActive()) {
    txn.rollback();
  }
}

Node.js

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Node.js.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

async function getTaskListEntities() {
  const transaction = datastore.transaction({readOnly: true});
  try {
    const taskListKey = datastore.key(['TaskList', 'default']);

    await transaction.run();
    const [taskList] = await transaction.get(taskListKey);
    const query = datastore.createQuery('Task').hasAncestor(taskListKey);
    const [taskListEntities] = await transaction.runQuery(query);
    await transaction.commit();
    return [taskList, taskListEntities];
  } catch (err) {
    await transaction.rollback();
  }
}

PHP

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore PHP.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

$transaction = $datastore->readOnlyTransaction();
$taskListKey = $datastore->key('TaskList', 'default');
$query = $datastore->query()
    ->kind('Task')
    ->hasAncestor($taskListKey);
$result = $transaction->runQuery($query);
$taskListEntities = [];
$num = 0;
/* @var Entity $task */
foreach ($result as $task) {
    $taskListEntities[] = $task;
    $num += 1;
}

Python

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Python.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

with client.transaction(read_only=True):
    task_list_key = client.key("TaskList", "default")

    task_list = client.get(task_list_key)

    query = client.query(kind="Task", ancestor=task_list_key)
    tasks_in_list = list(query.fetch())

    return task_list, tasks_in_list

Ruby

Per scoprire come installare e utilizzare la libreria client per Cloud Datastore, consulta Librerie client di Cloud Datastore. Per saperne di più, consulta la documentazione di riferimento dell'API Cloud Datastore Ruby.

Per eseguire l'autenticazione in Cloud Datastore, configura le Credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.

# task_list_name = "default"
task_list_key = datastore.key "TaskList", task_list_name
datastore.read_only_transaction do |tx|
  task_list = tx.find task_list_key
  query = datastore.query("Task").ancestor(task_list)
  tasks_in_list = tx.run query
end

Passaggi successivi

  • Scopri di più sulle query.