Struct aragog::transaction::Transaction[][src]

pub struct Transaction { /* fields omitted */ }

Struct representing a ArangoDB transaction.

Its pool is equivalent to a DatabaseConnectionPool but for transactional operations. Use it instead of the classic pool to use the streaming transaction.

Example


#[derive(Debug, Clone, Record, Validate, Serialize, Deserialize)]
pub struct User {
    pub field1: String,
    pub field2: String
}

let db_pool = DatabaseConnectionPool::builder()
    .build()
    .await
    .unwrap();
// Build a transaction pool from the main database pool
let transaction = Transaction::new(&db_pool).await.unwrap();
// Safely execute document operations in the transaction, the transaction will be closed afterwards
let result = transaction.safe_execute(|pool| async move {
    // All operations here will be transactional, if an error is raised, the transaction will be aborted.
    let doc = User {
        field1: String::from("foo"),
        field2: String::from("bar"),
    };
    // The closure safely checks for errors, use the `?` operator and avoid `unwrap()`
    let mut db_doc = DatabaseRecord::create(doc, &pool).await?;
    db_doc.field1 = String::from("not foo");
    db_doc.save(&pool).await?;
    Ok(db_doc)
}).await.unwrap();

// We make sure everything was committed
assert!(result.is_committed());
// We retrieve our document from the classic pool to check if it worked
let result = User::get(
    User::query().filter(Comparison::field("field1").equals_str("not foo").into()),
    &db_pool
).await.unwrap();
assert_eq!(result.len(), 1);

Note

The WRITE transaction operations muse be document related: create, save, delete, etc. The AQL operations may not work. On the other hand all READ operations as find, get, etc should all work even with AQL queries.

Implementations

impl Transaction[src]

pub async fn new(db_pool: &DatabaseConnectionPool) -> Result<Self, ServiceError>[src]

Instantiates a new Transaction from a DatabaseConnectionPool on all collections

Arguments

  • db_pool - The current database pool

The transaction will be initialized with default settings:

  • No disk writing wait (waitForSync)
  • A lock timeout of 60 000
  • No collection restriction

For more options use TransactionBuilder

pub async fn commit(&self) -> Result<(), ServiceError>[src]

Tries to commit all operations from the transaction

A Transaction instance can be committed multiple times.

Example


#[derive(Debug, Clone, Record, Validate, Serialize, Deserialize)]
pub struct User {
    pub field1: String,
    pub field2: String
}

// Build a transaction pool from the main database pool
let transaction = Transaction::new(&db_pool).await.unwrap();
let doc = User {
    field1: String::from("foo"),
    field2: String::from("bar"),
};
// Use the transaction pool instead of the standard `DatabaseConnectionPool`
match DatabaseRecord::create(doc, transaction.pool()).await {
    /// On the operation success we commit the complete pool of operations
    Ok(_) => transaction.commit().await.unwrap(),
    /// On the operation success we abort the complete pool of operations
    Err(_) => transaction.abort().await.unwrap()
}

Note

For a more practical and safer use, use the safe_execute method which allows multiple operations

pub async fn abort(&self) -> Result<(), ServiceError>[src]

Tries to abort all operations from the transaction.

If the operation succeeds, the ArangoDB transaction will be deleted and the current Transaction instance can't be used anymore.

Example


#[derive(Debug, Clone, Record, Validate, Serialize, Deserialize)]
pub struct User {
    pub field1: String,
    pub field2: String
}

// Build a transaction pool from the main database pool
let transaction = Transaction::new(&db_pool).await.unwrap();
let doc = User {
    field1: String::from("foo"),
    field2: String::from("bar"),
};
// Use the transaction pool instead of the standard `DatabaseConnectionPool`
match DatabaseRecord::create(doc, transaction.pool()).await {
    /// On the operation success we commit the complete pool of operations
    Ok(_) => transaction.commit().await.unwrap(),
    /// On the operation failure we abort the complete pool of operations
    Err(_) => transaction.abort().await.unwrap()
}

Note

For a more practical and safer use, use the safe_execute method which allows multiple operations

pub async fn safe_execute<T, O, F>(
    &self,
    operations: O
) -> Result<TransactionOutput<T>, ServiceError> where
    O: FnOnce(TransactionPool) -> F,
    F: Future<Output = Result<T, ServiceError>>, 
[src]

Allows to run multiple operations using the transaction pool. If an operation fails or an Err is returned by the closure, all operations will be aborted

Example


#[derive(Debug, Clone, Record, Validate, Serialize, Deserialize)]
pub struct User {
    pub field1: String,
    pub field2: String
}

// Build a transaction pool from the main database pool
let transaction = Transaction::new(&db_pool).await.unwrap();
// Safely execute document operations in the transaction
transaction.safe_execute(|pool| async move {
    // All operations here will be transactional, if an error is raised, the transaction will be aborted.
    let doc = User {
        field1: String::from("foo"),
        field2: String::from("bar"),
    };
    // The closure safely checks for errors, use the `?` operator and avoid `unwrap()`
    let mut db_doc = DatabaseRecord::create(doc, &pool).await?;
    db_doc.field1 = String::from("not foo");
    db_doc.save(&pool).await?;
    Ok(db_doc)
}).await.unwrap();

Note

Don't use unwrap() in the closure, as if the code panics the transaction won't be aborted nor commited.

pub fn pool(&self) -> &TransactionPool[src]

Retrieves the pool of the transaction which implements DatabaseAccess. This pool can be used exactly the same way was the classic database pool.

Trait Implementations

impl Deref for Transaction[src]

type Target = TransactionPool

The resulting type after dereferencing.

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> Instrument for T[src]

impl<T> Instrument for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.