Transactions

In transactions, requests to ArangoDB server are committed as a single, logical unit of work (ACID compliant).

Warning

New transaction REST API was added to ArangoDB version 3.5. In order to use it python-arango’s own transaction API had to be overhauled in version 5.0.0. The changes are not backward-compatible: context managers are no longer offered (you must always commit the transaction youself), method signatures are different when beginning the transaction, and results are returned immediately instead of job objects.

Example:

from arango import ArangoClient

# Initialize the ArangoDB client.
client = ArangoClient()

# Connect to "test" database as root user.
db = client.db('test', username='root', password='passwd')
col = db.collection('students')

# Begin a transaction. Read and write collections must be declared ahead of
# time. This returns an instance of TransactionDatabase, database-level
# API wrapper tailored specifically for executing transactions.
txn_db = db.begin_transaction(read=col.name, write=col.name)

# The API wrapper is specific to a single transaction with a unique ID.
txn_db.transaction_id

# Child wrappers are also tailored only for the specific transaction.
txn_aql = txn_db.aql
txn_col = txn_db.collection('students')

# API execution context is always set to "transaction".
assert txn_db.context == 'transaction'
assert txn_aql.context == 'transaction'
assert txn_col.context == 'transaction'

# From python-arango version 5+, results are returned immediately instead
# of job objects on API execution.
assert '_rev' in txn_col.insert({'_key': 'Abby'})
assert '_rev' in txn_col.insert({'_key': 'John'})
assert '_rev' in txn_col.insert({'_key': 'Mary'})

# Check the transaction status.
txn_db.transaction_status()

# Commit the transaction.
txn_db.commit_transaction()
assert 'Abby' in col
assert 'John' in col
assert 'Mary' in col
assert len(col) == 3

# Begin another transaction. Note that the wrappers above are specific to
# the last transaction and cannot be reused. New ones must be created.
txn_db = db.begin_transaction(read=col.name, write=col.name)
txn_col = txn_db.collection('students')
assert '_rev' in txn_col.insert({'_key': 'Kate'})
assert '_rev' in txn_col.insert({'_key': 'Mike'})
assert '_rev' in txn_col.insert({'_key': 'Lily'})
assert len(txn_col) == 6

# Abort the transaction
txn_db.abort_transaction()
assert 'Kate' not in col
assert 'Mike' not in col
assert 'Lily' not in col
assert len(col) == 3  # transaction is aborted so txn_col cannot be used

# Fetch an existing transaction. Useful if you have received a Transaction ID
# from some other part of your system or an external system.
original_txn = db.begin_transaction(write='students')
txn_col = original_txn.collection('students')
assert '_rev' in txn_col.insert({'_key': 'Chip'})
txn_db = db.fetch_transaction(original_txn.transaction_id)
txn_col = txn_db.collection('students')
assert '_rev' in txn_col.insert({'_key': 'Alya'})
txn_db.abort_transaction()

See TransactionDatabase for API specification.

Alternatively, you can use arango.database.StandardDatabase.execute_transaction() to run raw Javascript code in a transaction.

Example:

from arango import ArangoClient

# Initialize the ArangoDB client.
client = ArangoClient()

# Connect to "test" database as root user.
db = client.db('test', username='root', password='passwd')

# Get the API wrapper for "students" collection.
students = db.collection('students')

# Execute transaction in raw Javascript.
result = db.execute_transaction(
    command='''
    function () {{
        var db = require('internal').db;
        db.students.save(params.student1);
        if (db.students.count() > 1) {
            db.students.save(params.student2);
        } else {
            db.students.save(params.student3);
        }
        return true;
    }}
    ''',
    params={
        'student1': {'_key': 'Lucy'},
        'student2': {'_key': 'Greg'},
        'student3': {'_key': 'Dona'}
    },
    read='students',  # Specify the collections read.
    write='students'  # Specify the collections written.
)
assert result is True
assert 'Lucy' in students
assert 'Greg' in students
assert 'Dona' not in students