com.bigdata.service
Class AbstractTransactionService

java.lang.Object
  extended by com.bigdata.service.AbstractService
      extended by com.bigdata.service.AbstractTransactionService
All Implemented Interfaces:
ITimestampService, ITransactionService, IService, IServiceShutdown, Remote
Direct Known Subclasses:
DistributedTransactionService, JournalTransactionService

public abstract class AbstractTransactionService
extends AbstractService
implements ITransactionService, IServiceShutdown

Centalized transaction manager service. In response to a client request, the transaction manager will distribute prepare/commit or abort operations to all data services on which writes were made by a transaction. The transaction manager also provides global timestamps required for non-transactional commit points and various other purposes.

Version:
$Id: AbstractTransactionService.java 2265 2009-10-26 12:51:06Z thompsonbry $
Author:
Bryan Thompson
TODO:
failover. the service instances will need to track active/committed transactions, complain if their clocks get out of alignment, and refuse to generate a timestamp that would go backwards when compared to the timestamp generated by the last master service.

Nested Class Summary
static interface AbstractTransactionService.Options
          Options understood by this service.
protected  class AbstractTransactionService.TxState
          Transaction state as maintained by the ITransactionService.
 
Field Summary
protected  CounterSet countersRoot
           
protected static boolean DEBUG
           
protected static String ERR_NO_SUCH
          If the transaction is not known to this service.
protected static String ERR_NOT_ACTIVE
          If a transaction is no longer active.
protected static String ERR_READ_ONLY
          If the transaction is read-only and a write operation was requested.
protected static String ERR_SERVICE_NOT_AVAIL
          If the transaction service is not in a run state which permits the requested operation.
protected static boolean INFO
           
protected  ReentrantLock lock
          A lock used to serialize certain operations that must be atomic with respect to the state of the transaction service.
protected static org.apache.log4j.Logger log
          Logger.
protected  CommitTimeIndex startTimeIndex
          A transient index holding the absolute value of the start times of all active transactions.
protected  Condition txDeactivate
          Signalled by deactivateTx(TxState).
 
Constructor Summary
AbstractTransactionService(Properties properties)
           
 
Method Summary
 void abort(long tx)
          Abort the transaction (asynchronous).
protected abstract  void abortImpl(AbstractTransactionService.TxState state)
          Implementation must abort the tx on the journal (standalone) or on each data service (federation) on which it has written.
protected  void activateTx(AbstractTransactionService.TxState state)
          Adds the transaction from to the local tables.
protected  void assertOpen()
           
protected  long assignTransactionIdentifier(long timestamp)
          Assign a transaction identifier for a new transaction.
 long commit(long tx)
          Request commit of the transaction write set.
protected abstract  long commitImpl(AbstractTransactionService.TxState state)
          Implementation must either single-phase commit (standalone journal or a transaction that only writes on a single data service) or 2-/3-phase commit (distributed transaction running on a federation).
protected  void deactivateTx(AbstractTransactionService.TxState state)
          Removes the transaction from the local tables.
 void declareResources(long tx, UUID dataServiceUUID, String[] resource)
          Note: Only those DataServices on which a read-write transaction has started will participate in the commit.
 void destroy()
          Immediate/fast shutdown of the service and then destroys any persistent state associated with the service.
protected abstract  long findCommitTime(long timestamp)
          Find the commit time from which the tx will read (largest commitTime LTE timestamp).
protected abstract  long findNextCommitTime(long commitTime)
          Return the commit time for the successor of that commit point have the specified timestamp (a commit time strictly GT the given value).
protected  long findUnusedTimestamp(long commitTime, long nextCommitTime, long timeout, TimeUnit unit)
          Find a valid, unused timestamp.
 long getAbortCount()
          #of transaction aborted.
 int getActiveCount()
          The #of open transactions in any RunState.
 long getCommitCount()
          #of transaction committed.
 CounterSet getCounters()
          Return the CounterSet.
abstract  long getLastCommitTime()
          Note: Declared abstract so that we can hide the IOException.
 long getMinReleaseAge()
          Return the minimum #of milliseconds of history that must be preserved.
protected  Properties getProperties()
          An object wrapping the properties used to initialize the service.
 long getReadOnlyActiveCount()
           
 long getReadWriteActiveCount()
           
 long getReleaseTime()
          Return the timestamp whose historical data MAY be release.
 TxServiceRunState getRunState()
          Return the RunState.
 Class getServiceIface()
          Return the most interesting interface for the service.
 long getStartCount()
          #of transaction started.
protected  long getStartTime(long timestamp)
          Assign a distinct timestamp to a historical read that will read from the commit point identified by the specified timestamp.
 boolean isOpen()
          Any state other than TxServiceRunState.Halted.
 long newTx(long timestamp)
          Note: There is an upper bound of one read-write transaction that may be created per millisecond (the resolution of nextTimestamp()) and requests for new read-write transactions contend with other requests for nextTimestamp().
 long nextTimestamp()
          Return the next unique timestamp.
 void notifyCommit(long commitTime)
          The basic implementation advances the release time periodically as commits occur even when there are no transactions in use.
protected  void setReleaseTime(long newValue)
          Sets the new release time.
protected  void setRunState(TxServiceRunState newval)
          Change the TxServiceRunState.
 void shutdown()
          Polite shutdown.
 void shutdownNow()
          Fast shutdown (not immediate since it must abort active transactions).
 AbstractTransactionService start()
          Verifies that nextTimestamp() will not report a time before getLastCommitTime() and then changes the TxServiceRunState to TxServiceRunState.Running.
protected  void updateReleaseTime(long timestamp)
          This method is invoked each time a transaction completes with the absolute value of the transaction identifier that has just been deactivated.
 
Methods inherited from class com.bigdata.service.AbstractService
clearLoggingContext, getFederation, getHostname, getServiceName, getServiceUUID, setServiceUUID, setupLoggingContext
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface com.bigdata.journal.ITransactionService
committed, prepared
 
Methods inherited from interface com.bigdata.service.IService
getHostname, getServiceName, getServiceUUID
 

Field Detail

log

protected static final org.apache.log4j.Logger log
Logger.


INFO

protected static final boolean INFO

DEBUG

protected static final boolean DEBUG

ERR_READ_ONLY

protected static final transient String ERR_READ_ONLY
If the transaction is read-only and a write operation was requested.

See Also:
Constant Field Values

ERR_NO_SUCH

protected static final transient String ERR_NO_SUCH
If the transaction is not known to this service.

See Also:
Constant Field Values

ERR_NOT_ACTIVE

protected static final transient String ERR_NOT_ACTIVE
If a transaction is no longer active.

See Also:
Constant Field Values

ERR_SERVICE_NOT_AVAIL

protected static final transient String ERR_SERVICE_NOT_AVAIL
If the transaction service is not in a run state which permits the requested operation.

See Also:
Constant Field Values

lock

protected final ReentrantLock lock
A lock used to serialize certain operations that must be atomic with respect to the state of the transaction service. Mostly this is used to serialize the assignment of transaction identifiers and the update of the release time as transactions complete.


txDeactivate

protected final Condition txDeactivate
Signalled by deactivateTx(TxState).


startTimeIndex

protected final CommitTimeIndex startTimeIndex
A transient index holding the absolute value of the start times of all active transactions.

Note: The absolute value constraint is imposed so that we can directly identify the earliest active transaction in the index by its position (it will be at position zero). This would not work if we let in negative start times.

Note: In order to support this, #findUnusedTimestamp(long, long) will not return a timestamp whose absolute value corresponds to an active transaction.


countersRoot

protected CounterSet countersRoot
Constructor Detail

AbstractTransactionService

public AbstractTransactionService(Properties properties)
Method Detail

getProperties

protected Properties getProperties()
An object wrapping the properties used to initialize the service.


getActiveCount

public final int getActiveCount()
The #of open transactions in any RunState.


isOpen

public boolean isOpen()
Any state other than TxServiceRunState.Halted.

Specified by:
isOpen in interface IServiceShutdown

assertOpen

protected void assertOpen()

getRunState

public TxServiceRunState getRunState()
Return the RunState.


setRunState

protected void setRunState(TxServiceRunState newval)
Change the TxServiceRunState.

Parameters:
newval - The new value.
Throws:
IllegalStateException - if the requested state is not a legal state change.

shutdown

public void shutdown()
Polite shutdown. New transactions will not start. This method will block until existing transactions (both read-write and read-only) are complete (either aborted or committed).

Specified by:
shutdown in interface IServiceShutdown
Overrides:
shutdown in class AbstractService

shutdownNow

public void shutdownNow()
Fast shutdown (not immediate since it must abort active transactions).

New transactions will not start and active transactions will be aborted. Transactions which are concurrently committing MAY fail (throwing exceptions from various methods, including nextTimestamp()) when the service halts.

Specified by:
shutdownNow in interface IServiceShutdown
Overrides:
shutdownNow in class AbstractService

destroy

public void destroy()
Immediate/fast shutdown of the service and then destroys any persistent state associated with the service.

Specified by:
destroy in interface IService
Overrides:
destroy in class AbstractService

nextTimestamp

public final long nextTimestamp()
Description copied from interface: ITimestampService
Return the next unique timestamp. Timestamps must be strictly increasing.

Note: This method MUST return strictly increasing values, even when it is invoked by concurrent threads. While other implementations are possible and may be more efficient, one way to insure thread safety is to synchronize on some object such that the implementaiton exhibits a FIFO behavior.

Specified by:
nextTimestamp in interface ITimestampService
See Also:
TimestampServiceUtil.nextTimestamp(ITimestampService)

newTx

public long newTx(long timestamp)
Note: There is an upper bound of one read-write transaction that may be created per millisecond (the resolution of nextTimestamp()) and requests for new read-write transactions contend with other requests for nextTimestamp().

Note: The transaction service will refuse to start new transactions whose timestamps are LTE to #getEarliestTxStartTime().

Specified by:
newTx in interface ITransactionService
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:
RuntimeException - Wrapping TimeoutException if a timeout occurs awaiting a start time which would satisify the request for a read-only transaction (this can occur only for read-only transactions which must contend for start times which will read from the appropriate historical commit point).

getStartCount

public long getStartCount()
#of transaction started.


getAbortCount

public long getAbortCount()
#of transaction aborted.


getCommitCount

public long getCommitCount()
#of transaction committed.


getReadOnlyActiveCount

public long getReadOnlyActiveCount()

getReadWriteActiveCount

public long getReadWriteActiveCount()

getReleaseTime

public long getReleaseTime()
Description copied from interface: ITransactionService
Return the timestamp whose historical data MAY be release. 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 never be GT the last commit time. It will never be negative. It MAY be ZERO (0L) and will be ZERO (0L) on startup.

Specified by:
getReleaseTime in interface ITransactionService
See Also:
AbstractTransactionService.Options.MIN_RELEASE_AGE

setReleaseTime

protected void setReleaseTime(long newValue)
Sets the new release time.

Parameters:
newValue - The new value.

activateTx

protected void activateTx(AbstractTransactionService.TxState state)
Adds the transaction from to the local tables.

Parameters:
state - The transaction.

deactivateTx

protected void deactivateTx(AbstractTransactionService.TxState state)
Removes the transaction from the local tables.

Parameters:
state - The transaction.

updateReleaseTime

protected final void updateReleaseTime(long timestamp)
This method is invoked each time a transaction completes with the absolute value of the transaction identifier that has just been deactivated. The method will remove the transaction entry in the ordered set of running transactions (startTimeIndex). If the specified timestamp corresponds to the earliest running transaction, then the releaseTime will be updated and the new releaseTime will be set using setReleaseTime(long).

Note that the startTimeIndex contains the absolute value of the transaction identifers!

Parameters:
timestamp - The absolute value of a transaction identifier that has just been deactivated.
TODO:
the startTimeIndex could be used by #findUnusedTimestamp(long, long) so that it could further constrain its search within the half-open interval.

notifyCommit

public void notifyCommit(long commitTime)
The basic implementation advances the release time periodically as commits occur even when there are no transactions in use.

Note: This needs to be a fairly low-latency operation since this method is invoked for all commits on all data services and will otherwise be a global hotspot.

Specified by:
notifyCommit in interface ITransactionService
Parameters:
commitTime - The commit time.

getMinReleaseAge

public final long getMinReleaseAge()
Return the minimum #of milliseconds of history that must be preserved.

TODO:
This centralizes the value for the minimum amount of history that will be preserved across the federation.

If minReleaseTime is increased, then the release time can be changed to match, but only by NOT advancing it until we are retaining enough history.

If minReleaseTime is decreased, then we can immediately release more history (or at least as soon as the task runs to notify the discovered data services of the new release time).


assignTransactionIdentifier

protected long assignTransactionIdentifier(long timestamp)
                                    throws InterruptedException,
                                           TimeoutException
Assign a transaction identifier for a new transaction.

Parameters:
timestamp - The timestamp.
Returns:
The assigned transaction identifier.
Throws:
InterruptedException - if interrupted while awaiting a start time which would satisify the request.
InterruptedException - if a timeout occurs while awaiting a start time which would satisify the request.
TimeoutException

getStartTime

protected long getStartTime(long timestamp)
                     throws InterruptedException,
                            TimeoutException
Assign a distinct timestamp to a historical read that will read from the commit point identified by the specified timestamp.

Note: Under some circumstances the assignment of a read-only transaction identifier must be delayed until a distinct timestamp becomes available between the designed start time and the next commit point.

Parameters:
timestamp - The timestamp (identifies the desired commit point).
Returns:
A distinct timestamp not in use by any transaction that will read from the same commit point.
Throws:
InterruptedException
TimeoutException

findCommitTime

protected abstract long findCommitTime(long timestamp)
Find the commit time from which the tx will read (largest commitTime LTE timestamp).

Parameters:
timestamp - The timestamp.
Returns:
The commit time and -1L if there is no such commit time.

findNextCommitTime

protected abstract long findNextCommitTime(long commitTime)
Return the commit time for the successor of that commit point have the specified timestamp (a commit time strictly GT the given value).

Parameters:
commitTime - The probe.
Returns:
The successor or -1L iff the is no successor for that commit time.

findUnusedTimestamp

protected long findUnusedTimestamp(long commitTime,
                                   long nextCommitTime,
                                   long timeout,
                                   TimeUnit unit)
                            throws InterruptedException,
                                   TimeoutException
Find a valid, unused timestamp.

Note: Any timestamp in the half-open range [commitTime:nextCommitTime) MAY be assigned as all such timestamps will read from the commit point associated with [commitTime].

Parameters:
commitTime - The commit time for the commit point on which the tx will read (this must be the exact timestamp associated with the desired commit point).
nextCommitTime - The commit time for the successor of that commit point.
timeout - The maximum length of time to await an available timestamp.
unit - The unit in which timeout is expressed.
Throws:
InterruptedException
TimeoutException

getLastCommitTime

public abstract long getLastCommitTime()
Note: Declared abstract so that we can hide the IOException.

Specified by:
getLastCommitTime in interface ITransactionService
Returns:
The last known commit time.

abortImpl

protected abstract void abortImpl(AbstractTransactionService.TxState state)
                           throws Exception
Implementation must abort the tx on the journal (standalone) or on each data service (federation) on which it has written.

Pre-conditions:

  1. The transaction is RunState.Active; and
  2. The caller holds the AbstractTransactionService.TxState.lock.

Post-conditions:

  1. The transaction is RunState.Aborted; and
  2. The transaction write set has been discarded by each Journal or IDataService or which it has written (applicable for read-write transactions only).

Parameters:
state - The transaction state as maintained by the transaction server.
Throws:
Exception

commitImpl

protected abstract long commitImpl(AbstractTransactionService.TxState state)
                            throws Exception
Implementation must either single-phase commit (standalone journal or a transaction that only writes on a single data service) or 2-/3-phase commit (distributed transaction running on a federation).

Pre-conditions:

  1. The transaction is RunState.Active; and
  2. The caller holds the AbstractTransactionService.TxState.lock.

Post-conditions (success for read-only transaction or a read-write transaction with an empty write set):

  1. The transaction is RunState.Committed; and
  2. The returned commitTime is ZERO (0L).

Post-conditions (success for read-write transaction with a non-empty write set):

  1. The transaction is RunState.Committed;
  2. The transaction write set has been made restart-safe by each Journal or IDataService or which it has written (applicable for read-write transactions only); and
  3. The application can read exactly the data written by the transaction from the commit point identified by the returned commitTime.

Post-conditions (failure):

  1. The transaction is RunState.Aborted; and
  2. The transaction write set has been discarded by each Journal or IDataService or which it has written (applicable for read-write transactions only).

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.
Throws:
Exception - if something else goes wrong. This will be (or will wrap) a ValidationError if validation fails.

abort

public void abort(long tx)
Abort the transaction (asynchronous).

Specified by:
abort in interface ITransactionService
Parameters:
tx - The transaction identifier.

commit

public long commit(long tx)
            throws ValidationError
Description copied from interface: ITransactionService
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).

Specified by:
commit in interface ITransactionService
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.

declareResources

public void declareResources(long tx,
                             UUID dataServiceUUID,
                             String[] resource)
                      throws IllegalStateException
Note: Only those DataServices on which a read-write transaction has started will participate in the commit. If there is only a single such IDataService, then a single-phase commit will be used. Otherwise a distributed transaction commit protocol will be used.

Note: The commits requests are placed into a partial order by sorting the total set of resources which the transaction declares (via this method) across all operations executed by the transaction and then contending for locks on the named resources using a LockManager. This is handled by the DistributedTransactionService.

Specified by:
declareResources in interface ITransactionService
Parameters:
tx - The transaction identifier.
dataServiceUUID - 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:
IllegalStateException

start

public AbstractTransactionService start()
Verifies that nextTimestamp() will not report a time before getLastCommitTime() and then changes the TxServiceRunState to TxServiceRunState.Running.

Specified by:
start in class AbstractService
Returns:
this (the return type should be strengthened by the concrete implementation to return the actual type).

getServiceIface

public Class getServiceIface()
Description copied from class: AbstractService
Return the most interesting interface for the service.

Specified by:
getServiceIface in interface IService
Specified by:
getServiceIface in class AbstractService

getCounters

public CounterSet getCounters()
Return the CounterSet.

TODO:
define interface declaring the counters reported here.


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