Transaction(client, read_only=False)
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:
.. testsetup:: txn-put-multi, txn-api
import os
import uuid
from google.cloud import datastore
from tests.system.test_system import Config # system tests
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
client = datastore.Client(namespace='ns{}'.format(unique))
key1 = client.key('_Doctest')
entity1 = datastore.Entity(key=key1)
entity1['foo'] = 1337
key2 = client.key('_Doctest', 'abcd1234')
entity2 = datastore.Entity(key=key2)
entity2['foo'] = 42
Config.TO_DELETE.extend([entity1, entity2])
.. doctest:: txn-put-multi
>>> with client.transaction():
... client.put_multi([entity1, entity2])
Because it derives from xref_Batch,
Transaction
also provides put
and delete
methods:
.. doctest:: txn-api
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:
.. testsetup:: txn-error
import os
import uuid
from google.cloud import datastore
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
client = datastore.Client(namespace='ns{}'.format(unique))
def do_some_work():
return
class SomeException(Exception):
pass
.. doctest:: txn-error
>>> 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.
.. warning::
Inside a transaction, automatically assigned IDs for
entities will not be available at save time! That means, if you
try:
.. testsetup:: txn-entity-key, txn-entity-key-after, txn-manual
import os
import uuid
from google.cloud import datastore
from tests.system.test_system import Config # system tests
unique = os.getenv('CIRCLE_BUILD_NUM', str(uuid.uuid4())[0:8])
client = datastore.Client(namespace='ns{}'.format(unique))
def Entity(*args, **kwargs):
entity = datastore.Entity(*args, **kwargs)
Config.TO_DELETE.append(entity)
return entity
.. doctest:: txn-entity-key
>>> with client.transaction():
... entity = Entity(key=client.key('Thing'))
... client.put(entity)
entity
won't have a complete key until the transaction is
committed.
Once you exit the transaction (or call commit
), the
automatically generated ID will be assigned to the entity:
.. doctest:: txn-entity-key-after
>>> with client.transaction():
... entity = Entity(key=client.key('Thing'))
... client.put(entity)
... print(entity.key.is_partial) # There is no ID on this key.
...
True
>>> print(entity.key.is_partial) # There *is* an ID.
False
If you don't want to use the context manager you can initialize a transaction manually:
.. doctest:: txn-manual
transaction = client.transaction() transaction.begin()
entity = Entity(key=client.key('Thing')) transaction.put(entity)
transaction.commit()
Parameters
Name | Description |
client |
Client
the client used to connect to datastore. |
read_only |
bool
indicates the transaction is read only. |
Properties
id
Getter for the transaction ID.
Type | Description |
str | The ID of the current transaction. |
mutations
Getter for the changes accumulated by this batch.
Every batch is committed with a single commit request containing all
the work to be done as mutations. Inside a batch, calling put
with an entity, or delete
with a key, builds up the request by
adding a new mutation. This getter returns the protobuf that has been
built-up so far.
Type | Description |
iterable | The list of `.datastore_pb2.Mutation` protobufs to be sent in the commit request. |
namespace
Getter for namespace in which the batch will run.
Type | Description |
`str` | The namespace in which the batch will run. |
project
Getter for project in which the batch will run.
Type | Description |
`str` | The project in which the batch will run. |
Methods
begin
begin(retry=None, timeout=None)
Begins a transaction.
This method is called automatically when entering a with statement, however it can be called explicitly if you don't want to use a context manager.
Name | Description |
retry |
`google.api_core.retry.Retry`
A retry object used to retry requests. If |
timeout |
float
Time, in seconds, to wait for the request to complete. Note that if |
Type | Description |
`exceptions.ValueError | if the transaction has already begun. |
commit
commit(retry=None, timeout=None)
Commits the transaction.
This is called automatically upon exiting a with statement, however it can be called explicitly if you don't want to use a context manager.
This method has necessary side-effects:
- Sets the current transaction's ID to None.
Name | Description |
retry |
`google.api_core.retry.Retry`
A retry object used to retry requests. If |
timeout |
float
Time, in seconds, to wait for the request to complete. Note that if |
current
current()
Return the topmost transaction.
.. note::
If the topmost element on the stack is not a transaction,
returns None.
Type | Description |
Transaction or None | The current transaction (if any are active). |
delete
delete(key)
Remember a key to be deleted during commit
.
Name | Description |
key |
Key
the key to be deleted. |
Type | Description |
`exceptions.ValueError | if the batch is not in progress, if key is not complete, or if the key's ``project`` does not match ours. |
put
put(entity)
Adds an entity to be committed.
Ensures the transaction is not marked readonly. Please see documentation at xref_put
Name | Description |
entity |
Entity
the entity to be saved. |
Type | Description |
`RuntimeError | if the transaction is marked ReadOnly |
rollback
rollback(retry=None, timeout=None)
Rolls back the current transaction.
This method has necessary side-effects:
- Sets the current transaction's ID to None.
Name | Description |
retry |
`google.api_core.retry.Retry`
A retry object used to retry requests. If |
timeout |
float
Time, in seconds, to wait for the request to complete. Note that if |