Transaksi

Transaksi adalah sekumpulan operasi pada satu atau beberapa entitas. Setiap transaksi dijamin bersifat atomik, yang berarti transaksi tidak pernah diterapkan sebagian. Semua operasi dalam transaksi diterapkan, atau tidak ada yang diterapkan.

Menggunakan transaksi

Transaksi berakhir setelah 270 detik atau jika tidak ada aktivitas selama 60 detik.

Operasi mungkin gagal jika:

  • Terlalu banyak perubahan serentak yang dicoba pada entitas yang sama.
  • Transaksi melebihi batas resource.
  • Database mode Datastore mengalami error internal.

Dalam semua kasus ini, Datastore API akan menampilkan error.

Transaksi adalah fitur opsional. Anda tidak perlu menggunakan transaksi untuk melakukan operasi database.

Aplikasi dapat menjalankan kumpulan pernyataan dan operasi dalam satu transaksi, sehingga jika ada pernyataan atau operasi yang menimbulkan pengecualian, tidak ada satu pun operasi database dalam kumpulan yang diterapkan. Aplikasi menentukan tindakan yang akan dilakukan dalam transaksi.

Cuplikan berikut menunjukkan cara melakukan transaksi. Akun akan mentransfer uang dari satu rekening ke rekening lain.

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

/**
 * Update two entities in a transaction.
 *
 * @param DatastoreClient $datastore
 * @param Key $fromKey
 * @param Key $toKey
 * @param $amount
 */
function transfer_funds(
    DatastoreClient $datastore,
    Key $fromKey,
    Key $toKey,
    $amount
) {
    $transaction = $datastore->transaction();
    // 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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Perhatikan bahwa agar contoh kita lebih ringkas, terkadang kita menghilangkan rollback jika transaksi gagal. Dalam kode produksi, penting untuk memastikan bahwa setiap transaksi di-commit atau di-roll back secara eksplisit.

Yang dapat dilakukan dalam transaksi

Transaksi dapat mengkueri atau mencari sejumlah entitas. Ukuran maksimum transaksi adalah 10 MiB. Anda dapat menggunakan transaksi baca-tulis atau transaksi hanya baca.

Isolasi dan konsistensi

Database mode Datastore menerapkan isolasi serialisasi. Data yang dibaca atau diubah oleh transaksi tidak dapat diubah serentak.

Kueri dan pencarian dalam transaksi melihat snapshot yang konsisten dari status database. Snapshot ini dijamin berisi efek dari semua transaksi dan penulisan yang diselesaikan sebelum awal transaksi.

Tampilan snapshot yang konsisten ini juga meluas ke operasi baca setelah operasi tulis di dalam transaksi. Tidak seperti kebanyakan database, kueri dan pencarian di dalam transaksi mode Datastore tidak melihat hasil penulisan sebelumnya di dalam transaksi tersebut. Khususnya, jika suatu entitas diubah atau dihapus dalam transaksi, kueri atau pencarian akan menampilkan versi asli dari entitas tersebut sejak awal transaksi, atau tidak menampilkan apa pun jika entitas tersebut tidak ada pada saat itu.

Di luar transaksi, kueri dan pencarian juga memiliki isolasi serial.

Mode konkurensi

Firestore dalam mode Datastore mendukung tiga mode konkurensi. Mode serentak adalah setelan database yang menentukan cara transaksi serentak berinteraksi. Anda dapat memilih salah satu mode serentak berikut:

  • Pesimis

    Transaksi baca-tulis menggunakan kunci pembaca/penulis untuk menerapkan isolasi dan serialisasi. Jika dua atau beberapa transaksi baca-tulis serentak membaca atau menulis data yang sama, kunci yang ditahan oleh satu transaksi dapat menunda transaksi lainnya. Jika transaksi tidak memerlukan operasi tulis, Anda dapat meningkatkan performa dan menghindari pertentangan dengan transaksi lain menggunakan transaksi hanya baca. Transaksi hanya baca tidak memerlukan kunci apa pun.

    Firestore dalam database mode Datastore menggunakan mode konkurensi pesimis secara default.

  • Optimistik

    Saat dua atau beberapa transaksi baca-tulis serentak membaca atau menulis data yang sama, hanya transaksi pertama yang melakukan commit perubahannya yang berhasil. Transaksi lain yang melakukan penulisan gagal pada commit.

  • Optimistik Dengan Grup Entitas

    Gunakan mode serentak ini hanya jika aplikasi Anda bergantung pada semantik transaksional grup entity dari Cloud Datastore lama. Mode serentak ini memberikan batas tambahan pada transaksi:

    • Transaksi dibatasi hingga 25 grup entitas.
    • Operasi tulis ke entity group dibatasi 1 per detik.
    • Kueri dalam transaksi harus berupa kueri ancestor.

Melihat mode serentak

Gunakan resource REST projects.databases Firestore untuk melihat mode serentak database Anda:

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

Mengubah mode serentak

Untuk mengubah mode serentak database, kirim permintaan PATCH ke resource REST projects.databases 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"

dengan:

  • CONCURRENCY_MODE adalah PESSIMISTIC, OPTIMISTIC, atau OPTIMISTIC_WITH_ENTITY_GROUPS.
  • PROJECT_ID adalah ID project Google Cloud Anda.

Penggunaan transaksi

Salah satu kegunaan transaksi adalah memperbarui entity dengan nilai properti baru yang relatif terhadap nilainya saat ini. Contoh transferFunds di atas melakukannya untuk dua entitas, dengan menarik uang dari satu rekening dan mentransfernya ke akun lain. Datastore API tidak mencoba ulang transaksi secara otomatis, tetapi Anda dapat menambahkan logika Anda sendiri untuk mencobanya kembali, misalnya untuk menangani konflik saat permintaan lain memperbarui entity yang sama secara bersamaan.

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

/// <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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

$retries = 5;
for ($i = 0; $i < $retries; $i++) {
    try {
        transfer_funds($datastore, $fromKey, $toKey, 10);
    } catch (\Google\Cloud\Core\Exception\ConflictException $e) {
        // if $i >= $retries, the failure is final
        continue;
    }
    // Succeeded!
    break;
}

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

from google.cloud import datastore

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

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

(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

Hal ini memerlukan transaksi karena nilai balance dalam entity dapat diupdate oleh pengguna lain setelah kode ini mengambil objek, tetapi sebelum kode ini menyimpan objek yang telah diubah. Tanpa transaksi, permintaan pengguna tersebut akan menggunakan nilai balance sebelum update pengguna lain, dan file yang disimpan akan menimpa nilai baru. Dengan transaksi, aplikasi diberi tahu tentang update pengguna dari lain.

Penggunaan umum lainnya untuk transaksi adalah mengambil entity dengan kunci bernama, atau membuatnya jika belum ada (contoh ini dibuat berdasarkan contoh TaskList dari membuat entity):

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Go

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

_, 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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Python

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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():
    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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Seperti sebelumnya, diperlukan transaksi untuk menangani kasus saat pengguna lain mencoba membuat atau memperbarui entity dengan ID string yang sama. Tanpa transaksi, jika entitas tidak ada dan dua pengguna mencoba membuatnya, yang kedua akan menimpa entitas pertama tanpa mengetahui bahwa hal itu telah terjadi.

Jika transaksi gagal, Anda dapat meminta aplikasi mencoba ulang transaksi hingga berhasil, atau Anda dapat membiarkan pengguna menangani error dengan menyebarkannya ke tingkat antarmuka pengguna aplikasi. Anda tidak perlu membuat loop percobaan ulang di setiap transaksi.

Transaksi hanya baca

Terakhir, Anda dapat menggunakan transaksi untuk membaca snapshot database yang konsisten. Hal ini berguna ketika Anda memerlukan beberapa operasi baca untuk merender halaman atau mengekspor data yang harus konsisten. Untuk kasus ini, Anda dapat membuat transaksi hanya-baca.

Transaksi hanya baca tidak dapat mengubah entity, tetapi sebagai gantinya, transaksi tersebut tidak bersaing dengan transaksi lain dan tidak perlu dicoba lagi. Jika Anda hanya melakukan pembacaan dalam transaksi baca-tulis reguler, transaksi tersebut mungkin bersaing dengan transaksi yang mengubah data yang sama.

C#

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API C# Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Go Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Java Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Node.js Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API PHP Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

$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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Python Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

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

Untuk mempelajari cara menginstal dan menggunakan library klien untuk Cloud Datastore, lihat library klien Cloud Datastore. Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi API Ruby Cloud Datastore.

Untuk melakukan autentikasi ke Cloud Datastore, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

# 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

Langkah selanjutnya