Appearance
Transactions
Transactions ensure atomicity across multiple database operations. All queries within a transaction either commit together or roll back together.
begin_transaction(pool, cb) — Starting a Transaction
Gets a connection from the pool and begins a MySQL transaction. The callback receives the transaction object (shared_ptr<transaction>).
cpp
auto* pool = db.get_pool("primary");
pool->begin_transaction([](auto ec, auto tx) {
if (ec) {
fmt::println("Failed to start transaction: {}", ec.what());
return;
}
// Run queries within the transaction
tx->run([](auto ec, auto results) {
if (ec) return;
// Process results
}, "INSERT INTO users (name) VALUES (?)", {"Alice"});
});| Param | Type | Description |
|---|---|---|
cb | callback | Receives (error_code, shared_ptr<transaction>). The transaction is only valid within this callback. |
tx->run(cb, query, params) — Running Queries Inside a Transaction
Executes a query within the transaction context. Uses the same connection until commit or rollback.
run(cb, query) — Simple query:
cpp
tx->run([](auto ec, auto results) {
if (ec) { /* handle */ }
}, "SELECT * FROM users WHERE id = 1");run(cb, query, params) — Parameterized query:
cpp
tx->run([](auto ec, auto results) {
if (ec) return;
}, "UPDATE accounts SET balance = balance - ?", {100});tx->commit(cb) — Committing
Persists all changes made during the transaction.
cpp
tx->commit([](auto ec) {
if (!ec) fmt::println("Transaction committed!");
});tx->rollback(cb) — Rolling Back
Undoes all changes made during the transaction.
cpp
tx->rollback([](auto ec) {
fmt::println("Transaction rolled back");
});Chaining Multiple Queries
Chain queries sequentially, rolling back on any failure:
cpp
pool->begin_transaction([](auto ec, auto tx) {
if (ec) return;
tx->run([tx](auto ec, auto results) {
if (ec) return tx->rollback([](auto){});
tx->run([tx](auto ec, auto r2) {
if (ec) return tx->rollback([](auto){});
tx->commit([](auto ec) { });
}, "UPDATE accounts SET balance = balance - ?", {100});
}, "INSERT INTO transfers (amount) VALUES (?)", {100});
});Important: Capture tx by value in nested lambdas ([tx]), not by reference ([&tx]). The transaction may outlive the current scope — a reference capture will become a dangling pointer when the outer callback returns.
Checking Transaction State
cpp
bool finished = tx->is_finished(); // true after commit or rollback