Class OptimisticTransactionDb
- Namespace
- RocksDbNet
- Assembly
- RocksDb.Net.dll
A database whose transactions detect conflicts at commit rather than by
locking. Maps to rocksdb_optimistictransactiondb_t.
public sealed class OptimisticTransactionDb : RocksDbHandle, IDisposable
- Inheritance
-
OptimisticTransactionDb
- Implements
- Inherited Members
Remarks
Thread-safe except for disposal, as with RocksDb: dispose only once nothing else is using the database or a transaction from it.
The difference from TransactionDb is where the cost falls. A transaction database locks every key as it is written and holds the lock until the transaction ends, so a second writer waits for the lock timeout and then fails; it also keeps a lock manager and can deadlock. This takes no locks at all while a transaction runs. Instead Commit() checks that nothing it read or wrote has changed since, and fails if it has.
That trade is worth making when conflicts are rare and expensive to prevent — per-user or per-session keys that two writers almost never touch at once. It is the wrong trade under real contention, where every conflicting transaction does its work and then throws it away. A caller has to be prepared to retry: a failed commit here means "someone else got there first", not "the database is broken".
It also cannot deadlock, having no locks to wait on, so there is no lock timeout to tune and no deadlock detection to configure.
A separate type from RocksDb and TransactionDb rather than a subclass of either, for the same reason those are separate: RocksDb gives this a distinct native type with its own close, and it has no compaction, ingestion or range deletion of its own.
Opening takes ownership of the DbOptions and disposes them when the database closes. The OptimisticTransactionDbOptions are copied, so those may be disposed immediately.
The underlying non-transactional database is deliberately not exposed.
rocksdb_optimistictransactiondb_get_base_db hands back a
rocksdb_t* that must be released with
rocksdb_optimistictransactiondb_close_base_db rather than
rocksdb_close — wrapping it as a RocksDb would give
callers an object whose disposal closes the real database out from under
this one. TransactionDb withholds it for the same reason, and
the members worth reaching for through it are surfaced here directly.
Properties
ColumnFamilyNames
Names of the column families this database knows about.
public IReadOnlyCollection<string> ColumnFamilyNames { get; }
Property Value
Remarks
The default family is always in here, whether or not it was named when the database was opened, and GetColumnFamily(string) resolves it either way.
Methods
BeginTransaction(WriteOptions?, OptimisticTransactionOptions?)
Begins an optimistic transaction.
public Transaction BeginTransaction(WriteOptions? writeOptions = null, OptimisticTransactionOptions? transactionOptions = null)
Parameters
writeOptionsWriteOptionstransactionOptionsOptimisticTransactionOptions
Returns
Remarks
The returned transaction takes no locks. Reads and writes are buffered, and Commit() is where a conflict surfaces, as a RocksDbException. Treat that as a signal to retry rather than a failure.
Dispose it whether or not it committed, and before this database.
CreateCheckpoint()
Creates a checkpoint object for this database.
public Checkpoint CreateCheckpoint()
Returns
Remarks
Dispose the checkpoint before this database. It registers as a child, so the ordering is enforced rather than merely documented.
DisposeHandle()
Releases the native handle. Called during disposal.
protected override void DisposeHandle()
Remarks
Protected rather than public: it destroys the native object without marking this instance disposed or clearing the handle, so calling it from outside and then disposing normally would free the same pointer twice. It was the most Dispose-looking member on the type. Callers want Dispose().
DisposeUnmanagedResources()
Releases unmanaged resources used by the current instance.
protected override void DisposeUnmanagedResources()
Remarks
Protected for the same reason as DisposeHandle().
GetColumnFamily(string)
Looks up a column family named at open, throwing if there is none.
public ColumnFamilyHandle GetColumnFamily(string name)
Parameters
namestring
Returns
Exceptions
- KeyNotFoundException
No column family of that name is known.
GetDefaultColumnFamily()
Returns a non-owning wrapper around the default column family handle. Do not call Dispose on the returned handle — its lifetime is managed by the database.
public ColumnFamilyHandle GetDefaultColumnFamily()
Returns
Remarks
The handle is only reachable through the underlying non-transactional
database, since rocksdb_get_default_column_family_handle takes a
rocksdb_t*. rocksdb_transactiondb_get_base_db allocates a
rocksdb_t wrapper around a DB* this database owns, and
rocksdb_transactiondb_close_base_db deletes that wrapper and
nothing else — so the base database is not closed, and the column family
handle taken from it outlives the wrapper it came through.
Cached, because each call allocates a fresh
rocksdb_column_family_handle_t and the wrapper is non-owning, so
every call would otherwise leak one.
GetProperty(string)
Reads a string-valued RocksDb property.
public string? GetProperty(string propertyName)
Parameters
propertyNamestring
Returns
GetPropertyInt(string)
Reads an integer-valued RocksDb property.
public ulong? GetPropertyInt(string propertyName)
Parameters
propertyNamestring
Returns
Open(DbOptions, OptimisticTransactionDbOptions, string)
Opens, or creates, an optimistic transaction database at
path.
public static OptimisticTransactionDb Open(DbOptions options, OptimisticTransactionDbOptions optimisticOptions, string path)
Parameters
optionsDbOptionsoptimisticOptionsOptimisticTransactionDbOptionspathstring
Returns
Open(DbOptions, OptimisticTransactionDbOptions, string, IReadOnlyList<ColumnFamilyDescriptor>)
Opens, or creates, an optimistic transaction database with the given column families.
public static OptimisticTransactionDb Open(DbOptions options, OptimisticTransactionDbOptions optimisticOptions, string path, IReadOnlyList<ColumnFamilyDescriptor> columnFamilies)
Parameters
optionsDbOptionsoptimisticOptionsOptimisticTransactionDbOptionspathstringcolumnFamiliesIReadOnlyList<ColumnFamilyDescriptor>
Returns
Open(DbOptions, string)
Opens, or creates, an optimistic transaction database at
path.
public static OptimisticTransactionDb Open(DbOptions options, string path)
Parameters
Returns
Open(DbOptions, string, IReadOnlyList<ColumnFamilyDescriptor>)
Opens, or creates, an optimistic transaction database with the given column families.
public static OptimisticTransactionDb Open(DbOptions options, string path, IReadOnlyList<ColumnFamilyDescriptor> columnFamilies)
Parameters
optionsDbOptionspathstringcolumnFamiliesIReadOnlyList<ColumnFamilyDescriptor>
Returns
TryGetColumnFamily(string, out ColumnFamilyHandle?)
Looks up a column family, returning false rather than throwing when there is none.
public bool TryGetColumnFamily(string name, out ColumnFamilyHandle? columnFamily)
Parameters
namestringcolumnFamilyColumnFamilyHandle
Returns
Exceptions
- ObjectDisposedException
The handle registered for
namehas been disposed. The default family is the exception: it is resolved again instead.
Write(WriteBatch, WriteOptions?)
Applies a write batch straight to the database, without a transaction.
public void Write(WriteBatch batch, WriteOptions? options = null)
Parameters
batchWriteBatchoptionsWriteOptions
Remarks
Atomic, like any write batch, but not validated against anything: it bypasses conflict detection entirely rather than taking part in it. Use it for writes that no transaction is racing.