Connection pool
Rwf manages database connections automatically. Since Rwf apps are multi-threaded and asynchronous, a typical deployment will require multiple connections to the database to support concurrent requests. The connection pool takes care of creating and closing connections, and providing them to to the app as needed.
Get a connection
To execute queries with the ORM, you'll need to check out a connection from the pool. You can do so as follows from anywhere in the code:
Once you have a connection, you can pass it to the ORM each time you need to execute a query:
Return connection to the pool
Returning the connection to the pool is done automatically when the conn
variable goes out of scope. In Rust semantics, the conn
variable is "dropped". For example, to checkout a connection for only one query, you can do so inside its own scope:
async fn get_users() -> Result<Vec<User>, Error> {
let mut conn = Pool::connection().await?;
let users = User::all()
.fetch_all(&mut conn)
.await?;
Ok(users)
// The connection is returned to the pool here.
}
Transactions
All queries are executed inside implicit transactions. If you need to execute multiple queries inside a single transaction, you need to start one explicitly:
The transaction follows the same scope semantics as a pool connection. When it goes out scope,
the transaction is automatically rolled back and the connection is returned back to the pool. If you want to commit any changes you made inside the transaction, you need to call commit
explicitly:
Automatic rollbacks are a safety feature of Rwf connection management. In case an error happens in Rust mid-transaction, the changes are automatically reverted, preventing partial updates to the database.
Just like a connection, the transaction can be passed to any query generated with the ORM:
Waiting for connections
When all available connections are checked out, the call to Pool::connection()
will wait (and asynchronously block) until a connection is returned to the pool. If a connection is not returned in time, an timeout error will be returned, unblocking the request and allowing it to handle the situation gracefully.