Class SnapshotKVDatabase

java.lang.Object
io.permazen.kv.mvcc.SnapshotKVDatabase
All Implemented Interfaces:
KVDatabase
Direct Known Subclasses:
ArrayKVDatabase, LevelDBKVDatabase, MVStoreKVDatabase

@ThreadSafe public abstract class SnapshotKVDatabase extends Object implements KVDatabase
KVDatabase implementation based on an underlying AtomicKVStore using snapshot views and optimistic locking to provide concurrent transactions and linearizable ACID consistency.

Instances implement a simple optimistic locking scheme for MVCC using AtomicKVStore.readOnlySnapshot(). Concurrent transactions do not contend for any locks until commit time. During each transaction, reads are noted and derive from the snapshot, while writes are batched up. At commit time, if any other transaction has committed writes since the transaction's snapshot was created, and any of those writes conflict with any of the committing transaction's reads, a RetryTransactionException is thrown. Otherwise, the transaction is committed and its writes are applied.

Each outstanding transaction's mutations are batched up in memory using a Writes instance. Therefore, the transaction load supported by this class is limited to what can fit in memory.

Key watches are supported.

  • Field Details

    • log

      protected final Logger log
  • Constructor Details

    • SnapshotKVDatabase

      public SnapshotKVDatabase()
      Default constructor.

      The underlying key/value store must still be configured before starting this instance.

    • SnapshotKVDatabase

      public SnapshotKVDatabase(AtomicKVStore kvstore)
      Constructor.
      Parameters:
      kvstore - underlying key/value store
  • Method Details

    • getKVStore

      protected AtomicKVStore getKVStore()
      Get the underlying AtomicKVStore.
      Returns:
      underlying key/value store
    • setKVStore

      protected void setKVStore(AtomicKVStore kvstore)
      Configure the underlying AtomicKVStore.

      Required property; must be configured before start()ing.

      Parameters:
      kvstore - underlying key/value store
      Throws:
      IllegalStateException - if this instance is already started
    • getCurrentVersion

      public long getCurrentVersion()
      Get the current MVCC version number.
      Returns:
      MVCC database version number
    • start

      @PostConstruct public void start()
      Description copied from interface: KVDatabase
      Start this instance. This method must be called prior to creating any transactions.

      This method is idempotent: if this instance is already started, nothing happens.

      Whether an instance that has been started and stopped can be restarted is implementation-dependent.

      Specified by:
      start in interface KVDatabase
    • stop

      @PreDestroy public void stop()
      Description copied from interface: KVDatabase
      Stop this instance.

      This method is idempotent: if this instance has not been started, or is already stopped, nothing happens.

      Specified by:
      stop in interface KVDatabase
    • createTransaction

      public SnapshotKVTransaction createTransaction(Map<String,?> options)
      Description copied from interface: KVDatabase
      Create a new transaction with the specified options.
      Specified by:
      createTransaction in interface KVDatabase
      Parameters:
      options - optional transaction options; may be null
      Returns:
      newly created transaction
    • createTransaction

      public SnapshotKVTransaction createTransaction()
      Create a new transaction.
      Specified by:
      createTransaction in interface KVDatabase
      Returns:
      newly created transaction
      Throws:
      IllegalStateException - if not start()ed or stop()ing
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • createSnapshotKVTransaction

      protected SnapshotKVTransaction createSnapshotKVTransaction(MutableView view, long baseVersion)
      Instantiate a new SnapshotKVTransaction instance.

      The implementation in SnapshotKVDatabase just invokes the SnapshotKVTransaction constructor using this. Subclasses may want to override this method to create a more specific subclass.

      Parameters:
      view - mutable view to be used for this transaction
      baseVersion - the database version associated with base
      Returns:
      new transaction instance
      Throws:
      KVTransactionException - if an error occurs
    • closeTransactions

      protected void closeTransactions()
      Forcibly fail all outstanding transactions due to stop() being invoked.

      Can be used by subclasses during the shutdown sequence to ensure everything is properly cleaned up.

    • logException

      protected KVTransactionException logException(KVTransactionException e)
      Log specified exception. Used to ensure exceptions are logged at the point they are thrown.
      Parameters:
      e - exception to log
      Returns:
      e
    • wrapException

      protected RuntimeException wrapException(SnapshotKVTransaction tx, RuntimeException e)
      Wrap a RuntimeException as needed.

      The implementation in SnapshotKVDatabase just returns e.

      Parameters:
      tx - transaction in which the exception occurred
      e - original exception
      Returns:
      wrapped exception, or just e