class tensorstore.Transaction

Transactions are used to stage a group of modifications (e.g. writes to tensorstore.TensorStore objects) in memory, and then either commit the group all at once or abort it.

Two transaction modes are currently supported:

“Isolated” transactions provide write isolation: no modifications made are visible or persist outside the transactions until the transaction is committed. In addition to allowing modifications to be aborted/rolled back, this can also improve efficiency by ensuring multiple writes to the same underlying storage key are coalesced.

“Atomic isolated” transactions have all the properties of “isolated” transactions but additionally guarantee that all of the modifications will be committed atomically, i.e. at no point will an external reader observe only some but not all of the modifications. If the modifications made in the transaction cannot be committed atomically, the transaction will fail (without any changes being made).

Example usage:

>>> txn = ts.Transaction()
>>> store = ts.open({
...     'driver': 'n5',
...     'kvstore': {
...         'driver': 'file',
...         'path': 'tmp/dataset/'
...     },
...     'metadata': {
...         'dataType': 'uint16',
...         'blockSize': [2, 3],
...         'dimensions': [5, 6],
...         'compression': {
...             'type': 'raw'
...         }
...     },
...     'create': True,
...     'delete_existing': True
... }).result()
>>> store.with_transaction(txn)[1:4, 2:5] = 42
>>> store.with_transaction(txn)[0:2, 4] = 43

Uncommitted changes made in a transaction are visible from a transactional read using the same transaction, but not from a non-transactional read:

>>> store.with_transaction(txn).read().result()
array([[ 0,  0,  0,  0, 43,  0],
       [ 0,  0, 42, 42, 43,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0,  0,  0,  0,  0]], dtype=uint16)
>>> store.read().result()
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]], dtype=uint16)

The transaction can be committed using commit_async().

>>> txn.commit_async().result()
>>> store.read().result()
array([[ 0,  0,  0,  0, 43,  0],
       [ 0,  0, 42, 42, 43,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0,  0,  0,  0,  0]], dtype=uint16)

The tensorstore.Transaction class can also be used as a regular or asynchronous context manager:

>>> with ts.Transaction() as txn:
...     store.with_transaction(txn)[0:2, 1:3] = 44
...     store.with_transaction(txn)[0, 0] = 45
>>> store.read().result()
array([[45, 44, 44,  0, 43,  0],
       [ 0, 44, 44, 42, 43,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0,  0,  0,  0,  0]], dtype=uint16)
>>> async with ts.Transaction() as txn:
...     store.with_transaction(txn)[0:2, 1:3] = 44
...     store.with_transaction(txn)[0, 0] = 45
>>> await store.read()
array([[45, 44, 44,  0, 43,  0],
       [ 0, 44, 44, 42, 43,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0, 42, 42, 42,  0],
       [ 0,  0,  0,  0,  0,  0]], dtype=uint16)

If the block exits normally, the transaction is committed automatically. If the block raises an exception, the transaction is aborted.

Constructors

Transaction(atomic: bool = False, repeatable_read: bool = False)

Creates a new transaction.

Accessors

future : Future[None]

Commit result future.

aborted : bool

Indicates whether the transaction has been aborted.

commit_started : bool

Indicates whether the commit of the transaction has already started.

atomic : bool

Indicates whether the transaction is atomic.

open : bool

Indicates whether the transaction is still open.

Operations

commit_async() Future[None]

Asynchronously commits the transaction.

commit_sync() None

Synchronously commits the transaction.

abort() None

Aborts the transaction.