Struct aragog::transaction::Transaction [−][src]
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]
&self,
operations: O
) -> Result<TransactionOutput<T>, ServiceError> where
O: FnOnce(TransactionPool) -> F,
F: Future<Output = Result<T, ServiceError>>,
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.
fn deref(&self) -> &Self::Target
[src]
Auto Trait Implementations
impl !RefUnwindSafe for Transaction
impl Send for Transaction
impl Sync for Transaction
impl Unpin for Transaction
impl !UnwindSafe for Transaction
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T> Instrument for T
[src]
pub fn instrument(self, span: Span) -> Instrumented<Self>
[src]
pub fn in_current_span(self) -> Instrumented<Self>
[src]
impl<T> Instrument for T
[src]
pub fn instrument(self, span: Span) -> Instrumented<Self>
[src]
pub fn in_current_span(self) -> Instrumented<Self>
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,