![JAR search and dependency download from the Maven repository](/logo.png)
com.bigdata.journal.ITransactionService Maven / Gradle / Ivy
/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Mar 15, 2007
*/
package com.bigdata.journal;
import java.io.IOException;
import com.bigdata.btree.isolation.IConflictResolver;
import com.bigdata.service.IBigdataFederation;
import com.bigdata.service.IDataService;
/**
*
* An interface for managing transaction life cycles.
*
* Concurrency control
*
* The underlying concurrency control mechanism is Multi-Version Concurrency
* Control (MVCC). There are no "write locks" per say. Instead, a transaction
* reads from a historical commit point identified by its assigned start time
* (abs(transactionIdentifier) is a timestamp which identifies the commit point)
* and writes on an isolated write set visible only to that transaction. When a
* read-write transaction commits, its write set is validated against the then
* current committed state of the database. If validation succeeds, the isolated
* write set is merged down onto the database. Otherwise the transaction is
* aborted and its write set is discarded. (It is possible to register an index
* with an {@link IConflictResolver} in order to present the application with an
* opportunity to validate write-write conflicts using state-based techniques,
* i.e., by looking at the records and timestamps and making an informed
* decision).
*
*
* A transaction imposes "read locks" on the resources required for the
* historical state of the database from which that transaction is reading (both
* read-only and read-write transactions impose read locks). Those resources
* will not be released until the transaction is complete or aborted. The
* transaction manager coordinates the release of resources by advancing the
* global release time - the earliest commit time from which a transaction may
* read. Under dire circumstances (disk shortage) the transaction manager MAY
* choose to abort transactions and advance the release time in order to permit
* the release of locked resources and the reclamation of their space on local
* disk.
*
* Centralized transaction manager service
*
* When deployed as a distributed database there will be a centralized service
* implementing this interface and clients will discover and talk with that
* service. The centralized service in turn will coordinate the distributed
* transactions with the various {@link IDataService}s using their local
* implementations of this same interface. The centralized transaction service
* SHOULD invoke the corresponding methods on a {@link IDataService} IFF it
* knows that the {@link IDataService} is buffering writes for the transaction.
*
* Timestamps
*
* Both read-only and read-write transactions assert global read locks on the
* resources required for that historical state of the database corresponding to
* their start time. Those read locks are released when the transaction
* completes. Periodically the transaction manager will advance the release
* time, rendering views of earlier states of the database unavailable.
*
*
* The transaction identifier codes the transaction start time. The
* transaction start time is chosen from among those distinct timestamps
* available between the specified commit time and the next commit time on the
* database. Successive read-write transactions must be assigned transaction
* identifiers whose absolute value is strictly increasing - this requirement is
* introduced by the MVCC protocol.
*
*
* The sign of the transaction identifier indicates whether the transaction is
* read-only (positive) or read-write (negative). Read-only transaction
* identifiers may be directly used as commit times when reading on a local
* store. Read-write transaction identifiers must have their sign bit cleared in
* order to read from their ground state (the commit point corresponding to
* their transaction start time) but the unmodified transaction identifier is
* used to access their mutable view (the view comprised of the write set of the
* transaction super imposed on the ground state such that writes, overwrites,
* and deletes are visible in the view).
*
*
* The symbolic value {@link ITx#READ_COMMITTED} and any startTime
* MAY be used to perform a lightweight read-only operations either on a local
* data service or on the distributed database without coordination with the
* {@link ITransactionService}, but resources MAY be released at any time since
* no read "locks" have been declared. While a read-write transaction may be
* readily identified by the sign associated with the transaction identifier,
* you CAN NOT differentiate between a read-only transaction (with read-locks)
* and a lightweight read on a given commit time. In practice, it is only the
* transaction manager which needs to recognize read-only transactions and then
* only to constrain its assignment of distinct transaction identifiers and to
* coordinate the advance of the release time as transactions end. There is no
* other practical difference between read-only transactions and lightweight
* reads from the perspective of either the client or the individual data
* services as read-locks are managed solely through the advancement of the
* release time by the transaction manager.
*
*
* @author Bryan Thompson
*/
public interface ITransactionService extends ITimestampService {
/**
* Create a new transaction.
*
* @param timestamp
* The timestamp may be:
*
* - A timestamp (GT ZERO), which will result in a
* read-historical (read-only) transaction that reads from the
* most recent committed state whose commit timestamp is less
* than or equal to timestamp. (As a special case, a
* timestamp that is GT the
lastCommitTime
will
* produce a read-only transaction that is reading on the
* lastCommitTime
with snapshot isolation (new
* writes will not become visible in the view). This is basically
* the same behavior as specifying {@link ITx#READ_COMMITTED}.
* While perhaps counter-intuitive, this behavior is preferred to
* throwing an exception when a user attempts to read from a
* commit time GT the most recent commit point.).
* - The symbolic constant {@link ITx#READ_COMMITTED} to obtain
* a read-historical transaction reading from the most recently
* committed state of the database. The transaction will be
* assigned a start time corresponding to the most recent commit
* point of the database and will be a fully isolated read-only
* view of the state of the database as of that start time. (This
* is an atomic shorthand for newTx(getLastCommitTime())).
* - {@link ITx#UNISOLATED} for a read-write transaction.
*
*
* @return The unique transaction identifier.
*
* @throws IllegalStateException
* if the requested timestamp is for a commit point that is no
* longer preserved by the database (the resources for that
* commit point have been released).
* @throws IOException
* RMI errors.
*
* @todo specialize exception for a timestamp that is no longer preserved
* and for one that is in the future?
*/
// * @throws IllegalStateException
// * if the requested timestamp is greater than
// * {@link #getLastCommitTime()}.
long newTx(long timestamp) throws IOException;
/**
* Request commit of the transaction write set. Committing a read-only
* transaction is necessary in order to release read locks (this is very
* fast). If a transaction has a write set, then this method does not return
* until that write set has been made restart safe or the transaction has
* failed.
*
* The commit of a transaction with a write set on a single
* {@link IDataService} does not require either {@link ITx#UNISOLATED} tasks
* or other transactions to wait. The latency for such commits is directly
* related to the size of the transaction write set.
*
* However, the commit of a transaction with writes on more than one
* {@link IDataService} requires a distributed commit protocol. The
* distributed commit protocol forces ALL tasks writing on those
* {@link IDataService}s to wait until the transaction is complete. This is
* necessary in order to obtain a global commit point that corresponds to
* the atomic commit state of the transaction (without this we would not
* have the Atomic property for distributed transaction commits).
*
* @param tx
* The transaction identifier.
*
* @return The commit time for the transaction -or- ZERO (0L) if the
* transaction was read-only or had an empty write set. This commit
* time identifies a global commit point on the database from which
* you may read the coherent post-commit state of the transaction.
*
* @throws ValidationError
* if the transaction could not be validated.
* @throws IllegalStateException
* if tx is not an active transaction.
* @throws IOException
* RMI errors.
*/
long commit(long tx) throws ValidationError, IOException;
/**
* Request abort of the transaction write set.
*
* @param tx
* The transaction identifier.
*
* @throws IllegalStateException
* if tx is not an active transaction.
* @throws IOException
* RMI errors.
*/
void abort(long tx) throws IOException;
/**
* Notify the {@link ITransactionService} that a commit has been performed
* with the given timestamp (which it assigned) and that it should update
* its lastCommitTime iff the given commitTime is GT its current
* lastCommitTime.
*
* Note: This is used to inform the {@link ITransactionService} of commits
* that DO NOT involve transaction commits. That is, local unisolated writes
* on individual {@link IDataService}s in an {@link IBigdataFederation}.
*
* @param commitTime
* The commit time.
*
* @throws IOException
*/
void notifyCommit(long commitTime) throws IOException;
/**
* Return the last commitTime reported to the {@link ITransactionService}.
*
* @return The last known commit time.
*
* @throws IOException
*/
long getLastCommitTime() throws IOException;
/**
* Return the timestamp whose historical data MAY be released. This time is
* derived from the minimum of the timestamp of the earliest running
* transaction and now-minReleaseAge
and is updated whenever
* the earliest running transaction terminates. This value is monotonically
* increasing. It will always be LT the last non-zero last commit time. It
* will never be negative. It MAY be ZERO (0L) and will be ZERO (0L) on
* startup (unless explicitly set by the database to the last known commit
* time).
*
* The returned values is used to identify the most recent commit point LTE
* the releaseTime. This is the earliest commit point on whose data MAY be
* released. (Consequently, the first commit point GT the releaseTime is the
* earliest visible commit point.)
*/
long getReleaseTime() throws IOException;
}