txnStart method
Starts a new LMDB transaction.
A transaction represents a coherent set of changes to the database. All database operations must be performed within a transaction.
Parameters:
parent- Optional parent transaction for nested transactionsflags- Optional flags to modify transaction behavior
Common flags:
- MDB_RDONLY - Read-only transaction (better performance, multiple readers allowed)
- MDB_NOSYNC - Don't sync on commit (better performance but less safe)
Example usage patterns:
// 1. Basic read-write transaction
final txn = await db.txnStart();
try {
await db.putUtf8(txn, 'key', 'value');
await db.txnCommit(txn);
} catch (e) {
await db.txnAbort(txn);
rethrow;
}
// 2. Read-only transaction
final readTxn = await db.txnStart(
flags: LMDBFlagSet()..add(MDB_RDONLY)
);
try {
final value = await db.getUtf8(readTxn, 'key');
await db.txnCommit(readTxn);
} catch (e) {
await db.txnAbort(readTxn);
rethrow;
}
// 3. Nested transaction
final parentTxn = await db.txnStart();
try {
await db.putUtf8(parentTxn, 'key1', 'value1');
// Start a child transaction
final childTxn = await db.txnStart(parent: parentTxn);
try {
await db.putUtf8(childTxn, 'key2', 'value2');
await db.txnCommit(childTxn);
} catch (e) {
await db.txnAbort(childTxn);
rethrow;
}
await db.txnCommit(parentTxn);
} catch (e) {
await db.txnAbort(parentTxn);
rethrow;
}
Important notes:
- Always pair txnStart with either txnCommit or txnAbort
- Use try-catch blocks to ensure proper transaction handling
- Read-only transactions can run concurrently
- Only one write transaction can be active at a time
- Child transactions can only be created from write transactions
- Child transactions must be committed/aborted before parent transactions
Performance tips:
- Use read-only transactions when possible
- Keep transactions as short as possible
- Consider using MDB_NOSYNC for better write performance
- Use the Auto methods for simple operations
Throws StateError if database is not initialized Throws LMDBException if transaction cannot be started
Implementation
Future<Pointer<MDB_txn>> txnStart({
Pointer<MDB_txn>? parent,
LMDBFlagSet? flags,
}) async {
final currentEnv = env;
final txnPtr = calloc<Pointer<MDB_txn>>();
try {
final result = _lib.mdb_txn_begin(
currentEnv,
parent ?? nullptr,
flags?.value ?? LMDBFlagSet.defaultFlags.value,
txnPtr,
);
if (result != 0) {
throw LMDBException('Failed to start transaction', result);
}
return txnPtr.value;
} finally {
calloc.free(txnPtr);
}
}