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

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; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy