Table of Contents

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

IReadOnlyCollection<string>

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

writeOptions WriteOptions
transactionOptions OptimisticTransactionOptions

Returns

Transaction

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

Checkpoint

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

name string

Returns

ColumnFamilyHandle

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

ColumnFamilyHandle

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

propertyName string

Returns

string

GetPropertyInt(string)

Reads an integer-valued RocksDb property.

public ulong? GetPropertyInt(string propertyName)

Parameters

propertyName string

Returns

ulong?

Open(DbOptions, OptimisticTransactionDbOptions, string)

Opens, or creates, an optimistic transaction database at path.

public static OptimisticTransactionDb Open(DbOptions options, OptimisticTransactionDbOptions optimisticOptions, string path)

Parameters

options DbOptions
optimisticOptions OptimisticTransactionDbOptions
path string

Returns

OptimisticTransactionDb

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

options DbOptions
optimisticOptions OptimisticTransactionDbOptions
path string
columnFamilies IReadOnlyList<ColumnFamilyDescriptor>

Returns

OptimisticTransactionDb

Open(DbOptions, string)

Opens, or creates, an optimistic transaction database at path.

public static OptimisticTransactionDb Open(DbOptions options, string path)

Parameters

options DbOptions
path string

Returns

OptimisticTransactionDb

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

options DbOptions
path string
columnFamilies IReadOnlyList<ColumnFamilyDescriptor>

Returns

OptimisticTransactionDb

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

name string
columnFamily ColumnFamilyHandle

Returns

bool

Exceptions

ObjectDisposedException

The handle registered for name has 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

batch WriteBatch
options WriteOptions

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.