All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.hse_project.hse.KvdbTransaction Maven / Gradle / Ivy

/* SPDX-License-Identifier: Apache-2.0
 *
 * Copyright (C) 2021-2022 Micron Technology, Inc. All rights reserved.
 */

package io.github.hse_project.hse;

/**
 * The HSE KVDB provides transactions with operations spanning KVSs within a
 * single KVDB. These transactions have snapshot isolation (a specific form of
 * MVCC) with the normal semantics (see "Concurrency Control and Recovery in
 * Database Systems" by PA Bernstein).
 *
 * 

* One unusual aspect of the API as it relates to transactions is that the data * object that is used to hold client-level transaction state is allocated * separately from the transaction being initiated. As a result, the same object * handle should be reused again and again. *

* *

* In addition, there is very limited coupling between threading and * transactions. A single thread may have many transactions in flight * simultaneously. Also operations within a transaction can be performed by * multiple threads. The latter mode of operation must currently restrict calls * so that only one thread is actively performing an operation in the context of * a particular transaction at any particular time. *

* *

* The general lifecycle of a transaction is as follows: *

* *
 *                       +----------+
 *                       | INVALID  |
 *                       +----------+
 *                             |
 *                             v
 *                       +----------+
 *     +---------------->|  ACTIVE  |<----------------+
 *     |                 +----------+                 |
 *     |  +-----------+    |      |     +----------+  |
 *     +--| COMMITTED |<---+      +---->| ABORTED  |--+
 *        +-----------+                 +----------+
 * 
* *

* When a transaction is initially allocated, it starts in the INVALID state. * When {@link #begin()} is called with transaction in the INVALID, COMMITTED, * or ABORTED states, it moves to the ACTIVE state. It is an error to call the * {@link #begin()} function on a transaction in the ACTIVE state. For a * transaction in the ACTIVE state, only the functions {@link #commit()}, * {@link #abort()}, or {@link #close()} may be called (with the last doing an * abort prior to the free). *

* *

* When a transaction becomes ACTIVE, it establishes an ephemeral snapshot view * of the state of the KVDB. Any data mutations outside of the transaction's * context after that point are not visible to the transaction. Similarly, any * mutations performed within the context of the transaction are not visible * outside of the transaction unless and until it is committed. All such * mutations become visible atomically when the transaction commits. *

* *

* Within a transaction whenever a write operation e.g., put, delete, etc., * encounters a write conflict, that operation returns an error code of * ECANCELED. The caller is then expected to re-try the operation in a new * transaction. *

*/ public final class KvdbTransaction extends NativeObject implements AutoCloseable { /** KVDB the transaction is associated with. */ private final Kvdb kvdb; KvdbTransaction(final Kvdb kvdb) { this.kvdb = kvdb; this.handle = alloc(kvdb.handle); } private static native long alloc(long kvdbHandle); private native void abort(long kvdbHandle, long txnHandle) throws HseException; private native void begin(long kvdbHandle, long txnHandle) throws HseException; private native void commit(long kvdbHandle, long txnHandle) throws HseException; private native void free(long kvdbHandle, long txnHandle); private native State getState(long kvdbHandle, long txnHandle); /** * Abort/rollback transaction. * *

* The call fails if the referenced transaction is not in the ACTIVE state. *

* *

This function is thread safe.

* * @throws HseException Underlying C function returned a non-zero value. */ public void abort() throws HseException { abort(kvdb.handle, this.handle); } /** * Initiate transaction. * *

* The call fails if the transaction handle refers to an ACTIVE transaction. *

* *

This function is thread safe.

* * @throws HseException Underlying C function returned a non-zero value. */ public void begin() throws HseException { begin(kvdb.handle, this.handle); } /** * Close transaction. * *

* Commits the transaction if it is in the ACTIVE state. Otherwise, the * transaction is aborted. *

* *

This function is thread safe.

* * @throws HseException Underlying C function returned a non-zero value. */ @Override public void close() throws HseException { if (this.handle == 0) { return; } final State state = getState(); if (state == State.ACTIVE) { commit(); } else { abort(); } free(kvdb.handle, this.handle); this.handle = 0; } /** * Commit all the mutations of the referenced transaction. * *

* The call fails if the referenced transaction is not in the ACTIVE state. *

* *

This function is thread safe.

* * @throws HseException Underlying C function returned a non-zero value. */ public void commit() throws HseException { commit(kvdb.handle, this.handle); } /** * Get the state of the transaction. * *

This function is thread safe.

* * @return Transaction's state. */ public State getState() { return getState(kvdb.handle, this.handle); } /** Transaction state. */ public enum State { /** Invalid state. */ INVALID, /** Active state. */ ACTIVE, /** Committed state. */ COMMITTED, /** Aborted state. */ ABORTED, } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy