An abstraction representing datastore Transactions.
Transactions can be used to build up a bulk mutation and ensure all
or none succeed (transactionally).
For example, the following snippet of code will put the two save
operations (either insert or upsert) into the same
mutation, and execute those within a transaction:
Because it derives from xref_Batch,
Transaction also provides put and delete methods:
.. doctest:: txn
with client.transaction() as xact:
... xact.put(entity1)
... xact.delete(entity2.key)
By default, the transaction is rolled back if the transaction block
exits with an error:
.. doctest:: txn
>>> def do_some_work():
... return
>>> class SomeException(Exception):
... pass
>>> with client.transaction():
... do_some_work()
... raise SomeException # rolls back
Traceback (most recent call last):
...
SomeException
If the transaction block exits without an exception, it will commit
by default.
Once you exit the transaction (or call commit), the
automatically generated ID will be assigned to the entity:
.. doctest:: txn
>>> with client.transaction():
... thing2 = datastore.Entity(key=client.key('Thing'))
... client.put(thing2)
... print(thing2.key.is_partial) # There is no ID on this key.
...
True
>>> print(thing2.key.is_partial) # There *is* an ID.
False
If you don't want to use the context manager you can initialize a
transaction manually:
(Optional) Time at which the transaction reads entities. Only allowed when read_only=True. This feature is in private preview.
begin_later
bool
(Optional) If True, the transaction will be started lazily (i.e. when the first RPC is made). If False, the transaction will be started as soon as the context manager is entered. self.begin() can also be called manually to begin the transaction at any time. Default is False.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-28 UTC."],[],[],null,["# Module transaction (2.21.0)\n\nVersion latestkeyboard_arrow_down\n\n- [2.21.0 (latest)](/python/docs/reference/datastore/latest/google.cloud.datastore.transaction)\n- [2.20.2](/python/docs/reference/datastore/2.20.2/google.cloud.datastore.transaction)\n- [2.19.0](/python/docs/reference/datastore/2.19.0/google.cloud.datastore.transaction)\n- [2.18.0](/python/docs/reference/datastore/2.18.0/google.cloud.datastore.transaction)\n- [2.17.0](/python/docs/reference/datastore/2.17.0/google.cloud.datastore.transaction)\n- [2.16.1](/python/docs/reference/datastore/2.16.1/google.cloud.datastore.transaction)\n- [2.15.2](/python/docs/reference/datastore/2.15.2/google.cloud.datastore.transaction)\n- [2.14.0](/python/docs/reference/datastore/2.14.0/google.cloud.datastore.transaction)\n- [2.13.2](/python/docs/reference/datastore/2.13.2/google.cloud.datastore.transaction)\n- [2.12.0](/python/docs/reference/datastore/2.12.0/google.cloud.datastore.transaction)\n- [2.11.1](/python/docs/reference/datastore/2.11.1/google.cloud.datastore.transaction)\n- [2.10.0](/python/docs/reference/datastore/2.10.0/google.cloud.datastore.transaction)\n- [2.9.0](/python/docs/reference/datastore/2.9.0/google.cloud.datastore.transaction)\n- [2.8.3](/python/docs/reference/datastore/2.8.3/google.cloud.datastore.transaction)\n- [2.7.2](/python/docs/reference/datastore/2.7.2/google.cloud.datastore.transaction)\n- [2.6.2](/python/docs/reference/datastore/2.6.2/google.cloud.datastore.transaction)\n- [2.5.1](/python/docs/reference/datastore/2.5.1/google.cloud.datastore.transaction)\n- [2.4.0](/python/docs/reference/datastore/2.4.0/google.cloud.datastore.transaction)\n- [2.3.0](/python/docs/reference/datastore/2.3.0/google.cloud.datastore.transaction)\n- [2.2.0](/python/docs/reference/datastore/2.2.0/google.cloud.datastore.transaction)\n- [2.1.6](/python/docs/reference/datastore/2.1.6/google.cloud.datastore.transaction)\n- [2.0.1](/python/docs/reference/datastore/2.0.1/google.cloud.datastore.transaction)\n- [1.15.5](/python/docs/reference/datastore/1.15.5/google.cloud.datastore.transaction)\n- [1.14.0](/python/docs/reference/datastore/1.14.0/google.cloud.datastore.transaction)\n- [1.13.2](/python/docs/reference/datastore/1.13.2/google.cloud.datastore.transaction)\n- [1.12.0](/python/docs/reference/datastore/1.12.0/google.cloud.datastore.transaction)\n- [1.11.0](/python/docs/reference/datastore/1.11.0/google.cloud.datastore.transaction)\n- [1.10.0](/python/docs/reference/datastore/1.10.0/google.cloud.datastore.transaction)\n- [1.9.0](/python/docs/reference/datastore/1.9.0/google.cloud.datastore.transaction) \nCreate / interact with Google Cloud Datastore transactions.\n\nClasses\n-------\n\n### [Transaction](/python/docs/reference/datastore/latest/google.cloud.datastore.transaction.Transaction)\n\n Transaction(client, read_only=False, read_time=None, begin_later=False)\n\nAn abstraction representing datastore Transactions.\n\nTransactions can be used to build up a bulk mutation and ensure all\nor none succeed (transactionally).\n\nFor example, the following snippet of code will put the two `save`\noperations (either `insert` or `upsert`) into the same\nmutation, and execute those within a transaction:\n\n.. testsetup:: txn \n\n import uuid\n\n from google.cloud import https://cloud.google.com/python/docs/reference/datastore/latest/\n\n unique = str(uuid.uuid4())[0:8]\n client = https://cloud.google.com/python/docs/reference/datastore/latest/.https://cloud.google.com/python/docs/reference/datastore/latest/google.cloud.datastore.client.Client.html(namespace='ns{}'.format(unique))\n\n.. doctest:: txn \n\n \u003e\u003e\u003e entity1 = datastore.Entity(client.key('EntityKind', 1234))\n \u003e\u003e\u003e entity2 = datastore.Entity(client.key('EntityKind', 2345))\n \u003e\u003e\u003e with client.transaction():\n ... client.put_multi([entity1, entity2])\n\nBecause it derives from xref_Batch,\n`Transaction` also provides `put` and `delete` methods:\n\n.. doctest:: txn\n\u003e \u003e \u003e with client.transaction() as xact:\n\u003e \u003e \u003e ... xact.put(entity1)\n\u003e \u003e \u003e ... xact.delete(entity2.key)\n\nBy default, the transaction is rolled back if the transaction block\nexits with an error:\n\n.. doctest:: txn \n\n \u003e\u003e\u003e def do_some_work():\n ... return\n \u003e\u003e\u003e class SomeException(Exception):\n ... pass\n \u003e\u003e\u003e with client.transaction():\n ... do_some_work()\n ... raise SomeException # rolls back\n Traceback (most recent call last):\n ...\n SomeException\n\nIf the transaction block exits without an exception, it will commit\nby default.\n\n\u003cbr /\u003e\n\n| **Warning:** Inside a transaction, automatically assigned IDs for entities will not be available at save time! That means, if you try: .. doctest:: txn\n|\n|\n| \u003e \u003e \u003e with client.transaction():\n| \u003e \u003e \u003e ... thing1 = datastore.Entity(key=client.key('Thing'))\n| \u003e \u003e \u003e ... client.put(thing1)\nOnce you exit the transaction (or call `commit`), the automatically generated ID will be assigned to the entity:\n\n\u003cbr /\u003e\n\n.. doctest:: txn \n\n \u003e\u003e\u003e with client.transaction():\n ... thing2 = datastore.Entity(key=client.key('Thing'))\n ... client.put(thing2)\n ... print(thing2.key.is_partial) # There is no ID on this key.\n ...\n True\n \u003e\u003e\u003e print(thing2.key.is_partial) # There *is* an ID.\n False\n\nIf you don't want to use the context manager you can initialize a\ntransaction manually:\n\n.. doctest:: txn\n\u003e \u003e \u003e transaction = client.transaction()\n\u003e \u003e \u003e transaction.begin()\n\u003e \u003e \u003e\n\u003e \u003e \u003e thing3 = datastore.Entity(key=client.key('Thing'))\n\u003e \u003e \u003e transaction.put(thing3)\n\u003e \u003e \u003e\n\u003e \u003e \u003e transaction.commit()\n\n.. testcleanup:: txn \n\n with client.batch() as batch:\n batch.delete(client.key('EntityKind', 1234))\n batch.delete(client.key('EntityKind', 2345))\n batch.delete(thing1.key)\n batch.delete(thing2.key)\n batch.delete(thing3.key)"]]