Class TransactionStore


  • public class TransactionStore
    extends java.lang.Object
    A store that supports concurrent MVCC read-committed transactions.
    • Field Detail

      • store

        final MVStore store
        The store.
      • timeoutMillis

        final int timeoutMillis
        Default blocked transaction timeout
      • preparedTransactions

        private final MVMap<java.lang.Integer,​java.lang.Object[]> preparedTransactions
        The persisted map of prepared transactions. Key: transactionId, value: [ status, name ].
      • typeRegistry

        private final MVMap<java.lang.String,​DataType<?>> typeRegistry
      • undoLogs

        final MVMap<java.lang.Long,​Record<?,​?>>[] undoLogs
        Undo logs.

        If the first entry for a transaction doesn't have a logId of 0, then the transaction is partially committed (which means rollback is not possible). Log entries are written before the data is changed (write-ahead).

        Key: opId, value: [ mapId, key, oldValue ].

      • dataType

        private final DataType<?> dataType
      • openTransactions

        final java.util.concurrent.atomic.AtomicReference<VersionedBitSet> openTransactions
        This BitSet is used as vacancy indicator for transaction slots in transactions[]. It provides easy way to find first unoccupied slot, and also allows for copy-on-write non-blocking updates.
      • committingTransactions

        final java.util.concurrent.atomic.AtomicReference<java.util.BitSet> committingTransactions
        This is intended to be the source of ultimate truth about transaction being committed. Once bit is set, corresponding transaction is logically committed, although it might be plenty of "uncommitted" entries in various maps and undo record are still around. Nevertheless, all of those should be considered by other transactions as committed.
      • init

        private boolean init
      • maxTransactionId

        private int maxTransactionId
        Soft limit on the number of concurrently opened transactions. Not really needed but used by some test.
      • transactions

        private final java.util.concurrent.atomic.AtomicReferenceArray<Transaction> transactions
        Array holding all open transaction objects. Position in array is "transaction id". VolatileReferenceArray would do the job here, but there is no such thing in Java yet
      • TYPE_REGISTRY_NAME

        private static final java.lang.String TYPE_REGISTRY_NAME
        See Also:
        Constant Field Values
      • UNDO_LOG_NAME_PREFIX

        public static final java.lang.String UNDO_LOG_NAME_PREFIX
        The prefix for undo log entries.
        See Also:
        Constant Field Values
      • MAX_OPEN_TRANSACTIONS

        private static final int MAX_OPEN_TRANSACTIONS
        Hard limit on the number of concurrently opened transactions
        See Also:
        Constant Field Values
    • Constructor Detail

      • TransactionStore

        public TransactionStore​(MVStore store)
        Create a new transaction store.
        Parameters:
        store - the store
      • TransactionStore

        public TransactionStore​(MVStore store,
                                DataType<?> dataType)
      • TransactionStore

        public TransactionStore​(MVStore store,
                                MetaType<?> metaDataType,
                                DataType<?> dataType,
                                int timeoutMillis)
        Create a new transaction store.
        Parameters:
        store - the store
        metaDataType - the data type for type registry map values
        dataType - default data type for map keys and values
        timeoutMillis - lock acquisition timeout in milliseconds, 0 means no wait
    • Method Detail

      • getUndoLogName

        private static java.lang.String getUndoLogName​(int transactionId)
        Generate a string used to name undo log map for a specific transaction. This name will contain transaction id.
        Parameters:
        transactionId - of the corresponding transaction
        Returns:
        undo log name
      • init

        public void init()
        Initialize the store without any RollbackListener.
        See Also:
        init(RollbackListener)
      • init

        public void init​(TransactionStore.RollbackListener listener)
        Initialize the store. This is needed before a transaction can be opened. If the transaction store is corrupt, this method can throw an exception, in which case the store can only be used for reading.
        Parameters:
        listener - to notify about transaction rollback
      • markUndoLogAsCommitted

        private void markUndoLogAsCommitted​(int transactionId)
      • endLeftoverTransactions

        public void endLeftoverTransactions()
        Commit all transactions that are in the committed state, and rollback all open transactions.
      • getMaxTransactionId

        int getMaxTransactionId()
      • setMaxTransactionId

        public void setMaxTransactionId​(int max)
        Set the maximum transaction id, after which ids are re-used. If the old transaction is still in use when re-using an old id, the new transaction fails.
        Parameters:
        max - the maximum id
      • hasMap

        public boolean hasMap​(java.lang.String name)
        Check whether a given map exists.
        Parameters:
        name - the map name
        Returns:
        true if it exists
      • getOperationId

        static long getOperationId​(int transactionId,
                                   long logId)
        Combine the transaction id and the log id to an operation id.
        Parameters:
        transactionId - the transaction id
        logId - the log id
        Returns:
        the operation id
      • getTransactionId

        static int getTransactionId​(long operationId)
        Get the transaction id for the given operation id.
        Parameters:
        operationId - the operation id
        Returns:
        the transaction id
      • getLogId

        static long getLogId​(long operationId)
        Get the log id for the given operation id.
        Parameters:
        operationId - the operation id
        Returns:
        the log id
      • getOpenTransactions

        public java.util.List<Transaction> getOpenTransactions()
        Get the list of unclosed transactions that have pending writes.
        Returns:
        the list of transactions (sorted by id)
      • close

        public void close()
        Close the transaction store.
      • begin

        public Transaction begin()
        Begin a new transaction.
        Returns:
        the transaction
      • begin

        public Transaction begin​(TransactionStore.RollbackListener listener,
                                 int timeoutMillis,
                                 int ownerId,
                                 IsolationLevel isolationLevel)
        Begin a new transaction.
        Parameters:
        listener - to be notified in case of a rollback
        timeoutMillis - to wait for a blocking transaction
        ownerId - of the owner (Session?) to be reported by getBlockerId
        isolationLevel - of new transaction
        Returns:
        the transaction
      • storeTransaction

        void storeTransaction​(Transaction t)
        Store a transaction.
        Parameters:
        t - the transaction
      • addUndoLogRecord

        long addUndoLogRecord​(int transactionId,
                              long logId,
                              Record<?,​?> record)
        Add an undo log entry.
        Parameters:
        transactionId - id of the transaction
        logId - sequential number of the log record within transaction
        record - Record(mapId, key, previousValue) to add
        Returns:
        key for the added record
      • removeUndoLogRecord

        void removeUndoLogRecord​(int transactionId)
        Remove an undo log entry.
        Parameters:
        transactionId - id of the transaction
      • removeMap

        void removeMap​(TransactionMap<?,​?> map)
        Remove the given map.
        Parameters:
        map - the map
      • commit

        void commit​(Transaction t,
                    boolean recovery)
        Commit a transaction.
        Parameters:
        t - transaction to commit
        recovery - if called during initial transaction recovery procedure therefore undo log is stored under "committed" name already
      • flipCommittingTransactionsBit

        private void flipCommittingTransactionsBit​(int transactionId,
                                                   boolean flag)
      • openMap

        public <K,​V> MVMap<K,​V> openMap​(java.lang.String name,
                                                    DataType<K> keyType,
                                                    DataType<V> valueType)
        Open the map with the given name.
        Type Parameters:
        K - the key type
        V - the value type
        Parameters:
        name - the map name
        keyType - the key type
        valueType - the value type
        Returns:
        the map
      • openMap

        <K,​V> MVMap<K,​VersionedValue<V>> openMap​(int mapId)
        Open the map with the given id.
        Type Parameters:
        K - key type
        V - value type
        Parameters:
        mapId - the id
        Returns:
        the map
      • endTransaction

        void endTransaction​(Transaction t,
                            boolean hasChanges)
        End this transaction. Change status to CLOSED and vacate transaction slot. Will try to commit MVStore if autocommitDelay is 0 or if database is idle and amount of unsaved changes is sizable.
        Parameters:
        t - the transaction
        hasChanges - true if transaction has done any updates (even if they are fully rolled back), false if it just performed a data access
      • collectUndoLogRootReferences

        RootReference<java.lang.Long,​Record<?,​?>>[] collectUndoLogRootReferences()
        Get the root references (snapshots) for undo-log maps. Those snapshots can potentially be used to optimize TransactionMap.size().
        Returns:
        the array of root references or null if snapshotting is not possible
      • calculateUndoLogsTotalSize

        static long calculateUndoLogsTotalSize​(RootReference<java.lang.Long,​Record<?,​?>>[] undoLogRootReferences)
        Calculate the size for undo log entries.
        Parameters:
        undoLogRootReferences - the root references
        Returns:
        the number of key-value pairs
      • isUndoEmpty

        private boolean isUndoEmpty()
      • getTransaction

        Transaction getTransaction​(int transactionId)
        Get Transaction object for a transaction id.
        Parameters:
        transactionId - id for an open transaction
        Returns:
        Transaction object.
      • rollbackTo

        void rollbackTo​(Transaction t,
                        long maxLogId,
                        long toLogId)
        Rollback to an old savepoint.
        Parameters:
        t - the transaction
        maxLogId - the last log id
        toLogId - the log id to roll back to
      • getChanges

        java.util.Iterator<TransactionStore.Change> getChanges​(Transaction t,
                                                               long maxLogId,
                                                               long toLogId)
        Get the changes of the given transaction, starting from the latest log id back to the given log id.
        Parameters:
        t - the transaction
        maxLogId - the maximum log id
        toLogId - the minimum log id
        Returns:
        the changes