com.bigdata.journal
Interface ITransactionService

All Superinterfaces:
IService, ITimestampService, Remote
All Known Implementing Classes:
AbstractTransactionService, DelegateTransactionService, DistributedTransactionService, JournalTransactionService, TransactionServer.AdministrableTransactionService

public interface ITransactionService
extends ITimestampService

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 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 IDataServices using their local implementations of this same interface. The centralized transaction service SHOULD invoke the corresponding methods on a IDataService IFF it knows that the 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 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 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.

Version:
$Id: ITransactionService.java 4069 2011-01-09 20:58:02Z thompsonbry $
Author:
Bryan Thompson

Method Summary
 void abort(long tx)
          Request abort of the transaction write set.
 long commit(long tx)
          Request commit of the transaction write set.
 boolean committed(long tx, UUID dataService)
          Sent by a task participating in a distributed commit of a transaction when the task has successfully committed the write set of the transaction on the live journal of the local IDataService.
 void declareResources(long tx, UUID dataService, String[] resource)
          An IDataService MUST invoke this method before permitting an operation isolated by a read-write transaction to execute with access to the named resources (this applies only to distributed databases).
 long getLastCommitTime()
          Return the last commitTime reported to the ITransactionService.
 long getReleaseTime()
          Return the timestamp whose historical data MAY be released.
 long newTx(long timestamp)
          Create a new transaction.
 void notifyCommit(long commitTime)
          Notify the 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.
 long prepared(long tx, UUID dataService)
          Callback by an IDataService participating in a two phase commit for a distributed transaction.
 
Methods inherited from interface com.bigdata.journal.ITimestampService
nextTimestamp
 
Methods inherited from interface com.bigdata.service.IService
destroy, getHostname, getServiceIface, getServiceName, getServiceUUID
 

Method Detail

newTx

long newTx(long timestamp)
           throws IOException
Create a new transaction.

Parameters:
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.
  • The symbolic constant 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())).
  • ITx.UNISOLATED for a read-write transaction.
Returns:
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).
IOException - RMI errors.
TODO:
specialize exception for a timestamp that is no longer preserved and for one that is in the future?

commit

long commit(long tx)
            throws ValidationError,
                   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 IDataService does not require either 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 IDataService requires a distributed commit protocol. The distributed commit protocol forces ALL tasks writing on those IDataServices 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).

Parameters:
tx - The transaction identifier.
Returns:
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.
IllegalStateException - if tx is not an active transaction.
IOException - RMI errors.

abort

void abort(long tx)
           throws IOException
Request abort of the transaction write set.

Parameters:
tx - The transaction identifier.
Throws:
IllegalStateException - if tx is not an active transaction.
IOException - RMI errors.

notifyCommit

void notifyCommit(long commitTime)
                  throws IOException
Notify the 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 ITransactionService of commits that DO NOT involve transaction commits. That is, local unisolated writes on individual IDataServices in an IBigdataFederation.

Parameters:
commitTime - The commit time.
Throws:
IOException

getLastCommitTime

long getLastCommitTime()
                       throws IOException
Return the last commitTime reported to the ITransactionService.

Returns:
The last known commit time.
Throws:
IOException

getReleaseTime

long getReleaseTime()
                    throws IOException
Return the timestamp whose historical data MAY be released. This time is derived from the timestamp of the earliest running transaction MINUS the minimum release age 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).

Throws:
IOException

declareResources

void declareResources(long tx,
                      UUID dataService,
                      String[] resource)
                      throws IOException
An IDataService MUST invoke this method before permitting an operation isolated by a read-write transaction to execute with access to the named resources (this applies only to distributed databases). The declared resources are used in the commit phase of the read-write tx to impose a partial order on commits. That partial order guarantees that commits do not deadlock in contention for the same resources.

Parameters:
tx - The transaction identifier.
dataService - The UUID an IDataService on which the transaction will write.
resource - An array of the named resources which the transaction will use on that IDataService (this may be different for each operation submitted by that transaction to the IDataService).
Throws:
IOException

prepared

long prepared(long tx,
              UUID dataService)
              throws IOException,
                     InterruptedException,
                     BrokenBarrierException
Callback by an IDataService participating in a two phase commit for a distributed transaction. The ITransactionService will wait until all IDataServices have prepared. It will then choose a commitTime for the transaction and return that value to each IDataService.

Note: If this method throws ANY exception then the task MUST cancel the commit, discard the local write set of the transaction, and note that the transaction is aborted in its local state.

Parameters:
tx - The transaction identifier.
dataService - The UUID of the IDataService which sent the message.
Returns:
The assigned commit time.
Throws:
InterruptedException
BrokenBarrierException
IOException - if there is an RMI problem.

committed

boolean committed(long tx,
                  UUID dataService)
                  throws IOException,
                         InterruptedException,
                         BrokenBarrierException
Sent by a task participating in a distributed commit of a transaction when the task has successfully committed the write set of the transaction on the live journal of the local IDataService. If this method returns false then the distributed commit has failed and the task MUST rollback the live journal to the previous commit point. If the return is true then the distributed commit was successful and the task should halt permitting the IDataService to return from the ITxCommitProtocol.prepare(long, long) method.

Parameters:
tx - The transaction identifier.
dataService - The UUID of the IDataService which sent the message.
Returns:
true if the distributed commit was successfull and false if there was a problem.
Throws:
IOException
InterruptedException
BrokenBarrierException


Copyright © 2006-2012 SYSTAP, LLC. All Rights Reserved.