public abstract class AbstractTransactionService extends AbstractService implements ITransactionService, IServiceShutdown, ICounterSetAccess
Modifier and Type | Class and Description |
---|---|
static interface |
AbstractTransactionService.Options
Options understood by this service.
|
class |
AbstractTransactionService.TxState
Transaction state as maintained by the
ITransactionService . |
Modifier and Type | Field and Description |
---|---|
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 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 Condition |
txDeactivate
Signaled by
deactivateTx(TxState) and based on lock . |
Constructor and Description |
---|
AbstractTransactionService(Properties properties) |
Modifier and Type | Method and Description |
---|---|
void |
abort(long tx)
Abort the transaction (asynchronous).
|
void |
abortAllTx()
Abort all active transactions.
|
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 AbstractTransactionService.TxState |
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 |
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 . |
protected AbstractTransactionService.TxState |
getEarliestActiveTx()
Return the
AbstractTransactionService.TxState for the earliest active Tx -or-
null if there is no active tx. |
protected long |
getEffectiveReleaseTimeForHA()
This method was introduced to compute the effective timestamp of the
pinned history in support of the HA TXS.
|
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() |
protected long |
getReadsOnTime(long txId)
Return the commit time on which the transaction is reading.
|
long |
getReadWriteActiveCount() |
long |
getReleaseTime()
Return the timestamp whose historical data MAY be released.
|
TxServiceRunState |
getRunState()
Return the
RunState . |
Class |
getServiceIface()
Return the most interesting interface for the service.
|
long |
getStartCount()
#of transaction started.
|
protected AbstractTransactionService.TxState |
getTxState(long tx)
Return the
AbstractTransactionService.TxState associated with the specified transition
identifier. |
boolean |
isOpen()
Any state other than
TxServiceRunState.Halted . |
protected boolean |
isReleaseTimeConsensusProtocol()
Return
true iff the release time consensus protocol is being
used to update the releaseTime (HA and this service is either a leader or
a follower). |
long |
newTx(long timestamp)
Create a new transaction.
|
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,
AbstractTransactionService.TxState deactivatedTx)
This method MUST be invoked each time a transaction completes with the
absolute value of the transaction identifier that has just been
deactivated.
|
protected void |
updateReleaseTimeForBareCommit(long commitTime)
If there are NO active transactions and the current releaseTime is LT
(commitTime-1) then compute and set the new releaseTime.
|
clearLoggingContext, getFederation, getHostname, getServiceName, getServiceUUID, setServiceUUID, setupLoggingContext
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getHostname, getServiceName, getServiceUUID
protected static final org.apache.log4j.Logger log
protected static final transient String ERR_READ_ONLY
protected static final transient String ERR_NO_SUCH
protected static final transient String ERR_NOT_ACTIVE
protected static final transient String ERR_SERVICE_NOT_AVAIL
protected final ReentrantLock lock
Note: To avoid lock ordering problems DO NOT acquire this lock
if you are already holding a AbstractTransactionService.TxState.lock
. This causes a lock
ordering problem and can result in deadlock.
protected final Condition txDeactivate
deactivateTx(TxState)
and based on lock
.public AbstractTransactionService(Properties properties)
protected Properties getProperties()
protected AbstractTransactionService.TxState getTxState(long tx)
AbstractTransactionService.TxState
associated with the specified transition
identifier.
Note: This method is an internal API. The caller must adhere to the internal synchronization APIs for the transaction service.
tx
- The transaction identifier (the signed value, NOT the absolute
value).AbstractTransactionService.TxState
-or- null
if there is no such
active transaction.public final int getActiveCount()
RunState
.public boolean isOpen()
TxServiceRunState.Halted
.isOpen
in interface IServiceShutdown
protected void assertOpen()
public TxServiceRunState getRunState()
RunState
.protected void setRunState(TxServiceRunState newval)
TxServiceRunState
.newval
- The new value.IllegalStateException
- if the requested state is not a legal state change.public void shutdown()
shutdown
in interface IServiceShutdown
shutdown
in class AbstractService
public void shutdownNow()
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.
shutdownNow
in interface IServiceShutdown
shutdownNow
in class AbstractService
public void abortAllTx()
public void destroy()
destroy
in interface IService
destroy
in class AbstractService
public long nextTimestamp()
ITimestampService
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.
nextTimestamp
in interface ITimestampService
TimestampServiceUtil.nextTimestamp(ITimestampService)
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 getReleaseTime()
.
newTx
in interface ITransactionService
timestamp
- The timestamp may be:
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 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.).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.RuntimeException
- Wrapping TimeoutException
if a timeout occurs
awaiting a start time which would satisfy 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).public long getStartCount()
public long getAbortCount()
public long getCommitCount()
public long getReadOnlyActiveCount()
public long getReadWriteActiveCount()
protected AbstractTransactionService.TxState getEarliestActiveTx()
AbstractTransactionService.TxState
for the earliest active Tx -or-
null
if there is no active tx.
Note: The lock
is required in order to make atomic decisions
about the earliest active tx. Without the lock
, the tx could
stop or a new tx could start, thereby invalidating the "earliest active"
guarantee.
IllegalMonitorStateException
- unless the lock
is held by the caller.public long getReleaseTime()
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.)
getReleaseTime
in interface ITransactionService
AbstractTransactionService.Options.MIN_RELEASE_AGE
protected void setReleaseTime(long newValue)
Note: For a joined service in HA (the leader or a follower), the release
time is set by the consensus protocol. Otherwise it is automatically
maintained by updateReleaseTime(long, TxState)
and
updateReleaseTimeForBareCommit(long)
.
newValue
- The new value.protected long getEffectiveReleaseTimeForHA()
releaseTime
and reports the minimum of
now - minReleaseAge
and the readsOnCommitTime of the
earliest active Tx. If the value would be negative, then ZERO (0L) is
reported instead.
Note: This duplicates logic in #updateReleaseTime(long)
, but
handles the special case in HA where the releaseTime is not being updated
by updateReleaseTimeForBareCommit(long)
.
#updateReleaseTime(long)
protected void activateTx(AbstractTransactionService.TxState state)
state
- The transaction.protected long getReadsOnTime(long txId)
Note: This method is exposed primarily for the unit tests.
txId
- The transaction identifier.IllegalArgumentException
- if there is no such transaction.protected void deactivateTx(AbstractTransactionService.TxState state)
Note: The caller MUST own AbstractTransactionService.TxState.lock
across this method and
MUST then do
updateReleaseTime(long) deactivateTx.signallAll()while holding the outer
lock
.
Note: Normally this method is invoked without the outer lock
which necessitates lifting those method calls out of this method and into
the caller.
state
- The transaction.IllegalMonitorStateException
- unless the caller is holding the AbstractTransactionService.TxState.lock
.protected boolean isReleaseTimeConsensusProtocol()
true
iff the release time consensus protocol is being
used to update the releaseTime (HA and this service is either a leader or
a follower). Return false
iff the service should locally
manage its own release time (non-HA and HA when the service is
HAStatusEnum.NotReady
).
Note: When we are using a 2-phase commit, the leader can not update the release time from commit() using this methods. It must rely on the consensus protocol to update the release time instead.
protected final void updateReleaseTime(long timestamp, AbstractTransactionService.TxState deactivatedTx)
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)
. For HA,
the releaseTime is updated by a consensus protocol and the individual
services MUST NOT advance their releaseTime as transactions complete.
Note: When we are using a 2-phase commit, the leader can not update the release time from commit() using this methods. It must rely on the consensus protocol to update the release time instead.
timestamp
- The absolute value of a transaction identifier that has just
been deactivated.deactivatedTx
- The transaction object that has been deactivated -or-
null
if there are known to be no active
transactions remaining (e.g., startup and abortAll()).public void notifyCommit(long commitTime)
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.
notifyCommit
in interface ITransactionService
commitTime
- The commit time.protected void updateReleaseTimeForBareCommit(long commitTime)
Note: This method was historically part of notifyCommit(long)
.
It was moved into its own method so it can be overridden for some unit
tests.
Note: When we are using a 2-phase commit, the leader can not update the release time from commit() using this methods. It must rely on the consensus protocol to update the release time instead.
public final long getMinReleaseAge()
protected final AbstractTransactionService.TxState assignTransactionIdentifier(long timestamp) throws InterruptedException, TimeoutException
timestamp
- The timestamp.InterruptedException
- if interrupted while awaiting a start time which would
satisfy the request.InterruptedException
- if a timeout occurs while awaiting a start time which would
satisfy the request.TimeoutException
protected abstract long findCommitTime(long timestamp)
timestamp
- The timestamp.protected abstract long findNextCommitTime(long commitTime)
commitTime
- The probe.protected long findUnusedTimestamp(long commitTime, long nextCommitTime, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
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].
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.InterruptedException
TimeoutException
public abstract long getLastCommitTime()
IOException
.getLastCommitTime
in interface ITransactionService
protected abstract void abortImpl(AbstractTransactionService.TxState state) throws Exception
Pre-conditions:
RunState.Active
; andAbstractTransactionService.TxState.lock
.Post-conditions:
RunState.Aborted
; andJournal
or IDataService
or which it has written (applicable for
read-write transactions only).state
- The transaction state as maintained by the transaction server.Exception
protected abstract long commitImpl(AbstractTransactionService.TxState state) throws Exception
Pre-conditions:
RunState.Active
; andAbstractTransactionService.TxState.lock
.Post-conditions (success for read-only transaction or a read-write transaction with an empty write set):
RunState.Committed
; andPost-conditions (success for read-write transaction with a non-empty write set):
RunState.Committed
;Journal
or IDataService
or which it has written
(applicable for read-write transactions only); andPost-conditions (failure):
RunState.Aborted
; andJournal
or IDataService
or which it has written (applicable for
read-write transactions only).tx
- The transaction identifier.Exception
- if something else goes wrong. This will be (or will wrap) a
ValidationError
if validation fails.public void abort(long tx)
abort
in interface ITransactionService
tx
- The transaction identifier.public long commit(long tx) throws ValidationError
ITransactionService
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
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).
commit
in interface ITransactionService
tx
- The transaction identifier.ValidationError
- if the transaction could not be validated.public AbstractTransactionService start()
nextTimestamp()
will not report a time before
getLastCommitTime()
and then changes the TxServiceRunState
to TxServiceRunState.Running
.start
in class AbstractService
public Class getServiceIface()
AbstractService
getServiceIface
in interface IService
getServiceIface
in class AbstractService
public CounterSet getCounters()
CounterSet
.getCounters
in interface ICounterSetAccess
Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.