public abstract class DistributedTransactionService extends AbstractTransactionService implements IDistributedTransactionService
IBigdataFederation
supporting both single-phase
commits (for transactions that execute on a single IDataService
) and
distributed commits.Modifier and Type | Class and Description |
---|---|
protected class |
DistributedTransactionService.NotifyReleaseTimeTask
Task periodically notifies the discovered
IDataService s of the
new release time. |
static interface |
DistributedTransactionService.Options
Options understood by this service.
|
static class |
DistributedTransactionService.SnapshotHelper
A helper class for reading and writing snapshots of the commit time
index.
|
AbstractTransactionService.TxState
Modifier and Type | Field and Description |
---|---|
protected static String |
BASENAME
Basename for the files written in the
dataDir containing images
of the commitTimeIndex . |
protected CommitTimeIndex |
commitTimeIndex
A
BTree containing a log of the historical commit points. |
protected File |
dataDir
The data directory -or-
null iff the service is transient. |
protected static String |
EXT
Extension for the files written in the
dataDir containing
snapshots of the commitTimeIndex . |
ERR_NO_SUCH, ERR_NOT_ACTIVE, ERR_READ_ONLY, ERR_SERVICE_NOT_AVAIL, lock, log, txDeactivate
Constructor and Description |
---|
DistributedTransactionService(Properties properties) |
Modifier and Type | Method and Description |
---|---|
protected 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 |
addScheduledTasks()
Adds the scheduled tasks.
|
protected long |
commitImpl(AbstractTransactionService.TxState state)
There are two distinct commit protocols depending on whether the
transaction write set is distributed across more than one
IDataService . |
boolean |
committed(long tx,
UUID dataService)
Wait at "committed" barrier.
|
void |
declareResources(long tx,
UUID dataServiceUUID,
String[] resource)
Note: Only those
DataService s 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 long |
findCommitTime(long timestamp)
Find the commit time from which the tx will read (largest commitTime LTE
timestamp).
|
protected 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).
|
CounterSet |
getCounters()
Adds counters for the
LockManager . |
protected ITxCommitProtocol[] |
getDataServices(UUID[] uuids)
Return the proxies for the services participating in a distributed
transaction commit or abort.
|
long |
getLastCommitTime()
Note: Declared abstract so that we can hide the
IOException . |
void |
notifyCommit(long commitTime)
The basic implementation advances the release time periodically as
commits occur even when there are no transactions in use.
|
long |
prepared(long tx,
UUID dataService)
Waits at "prepared" barrier.
|
protected void |
setReleaseTime(long releaseTime)
Extended to truncate the head of the
commitTimeIndex such only
the commit times requires for reading on timestamps GTE to the new
releaseTime are retained. |
void |
shutdown()
Polite shutdown.
|
void |
shutdownNow()
Fast shutdown (not immediate since it must abort active transactions).
|
protected long |
singlePhaseCommit(AbstractTransactionService.TxState state)
Prepare and commit a read-write transaction that has written on a single
data service.
|
void |
snapshot()
Runs the
SnapshotTask once. |
DistributedTransactionService |
start()
Verifies that
AbstractTransactionService.nextTimestamp() will not report a time before
AbstractTransactionService.getLastCommitTime() and then changes the TxServiceRunState
to TxServiceRunState.Running . |
abort, abortAllTx, activateTx, assertOpen, assignTransactionIdentifier, commit, deactivateTx, findUnusedTimestamp, getAbortCount, getActiveCount, getCommitCount, getEarliestActiveTx, getEffectiveReleaseTimeForHA, getMinReleaseAge, getProperties, getReadOnlyActiveCount, getReadsOnTime, getReadWriteActiveCount, getReleaseTime, getRunState, getServiceIface, getStartCount, getTxState, isOpen, isReleaseTimeConsensusProtocol, newTx, nextTimestamp, setRunState, updateReleaseTime, updateReleaseTimeForBareCommit
clearLoggingContext, getFederation, getHostname, getServiceName, getServiceUUID, setServiceUUID, setupLoggingContext
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
abort, commit, getReleaseTime, newTx
nextTimestamp
getHostname, getServiceIface, getServiceName, getServiceUUID
protected final CommitTimeIndex commitTimeIndex
BTree
containing a log of the historical commit points.
The main things that it gives us are (a) the half-open ranges within which we can allocate read-historical transactions; and (b) the last commit time on record. It seems that creating an image of the log every N seconds should be sufficient.
Note: Read and write operations on this index MUST be synchronized on the index object.
protected final File dataDir
null
iff the service is transient.protected static final String BASENAME
dataDir
containing images
of the commitTimeIndex
.protected static final String EXT
dataDir
containing
snapshots of the commitTimeIndex
.public DistributedTransactionService(Properties properties)
properties
- public void snapshot()
SnapshotTask
once.public DistributedTransactionService start()
AbstractTransactionService
AbstractTransactionService.nextTimestamp()
will not report a time before
AbstractTransactionService.getLastCommitTime()
and then changes the TxServiceRunState
to TxServiceRunState.Running
.start
in class AbstractTransactionService
protected void addScheduledTasks()
public void shutdown()
AbstractTransactionService
shutdown
in interface IServiceShutdown
shutdown
in class AbstractTransactionService
public void shutdownNow()
AbstractTransactionService
New transactions will not start and active transactions will be aborted.
Transactions which are concurrently committing MAY fail (throwing
exceptions from various methods, including AbstractTransactionService.nextTimestamp()
)
when the service halts.
shutdownNow
in interface IServiceShutdown
shutdownNow
in class AbstractTransactionService
public void destroy()
AbstractTransactionService
destroy
in interface IService
destroy
in class AbstractTransactionService
protected void setReleaseTime(long releaseTime)
commitTimeIndex
such only
the commit times requires for reading on timestamps GTE to the new
releaseTime are retained.setReleaseTime
in class AbstractTransactionService
releaseTime
- The new value.protected ITxCommitProtocol[] getDataServices(UUID[] uuids)
Note: This method is here so that it may be readily overriden for unit tests.
uuids
- The UUID
s of the participating services.protected void abortImpl(AbstractTransactionService.TxState state) throws Exception
AbstractTransactionService
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).abortImpl
in class AbstractTransactionService
state
- The transaction state as maintained by the transaction server.Exception
protected long commitImpl(AbstractTransactionService.TxState state) throws Exception
IDataService
. When write set of the transaction lies entirely on
a single IDataService
, an optimized commit protocol is used.
When the write set of the transaction is distributed, a 3-phase commit is
used with most of the work occurring during the "prepare" phase and a
very rapid "commit" phase. If a distributed commit fails, even during the
"commit", then the transaction will be rolled back on all participating
IDataService
s.
IDataService
. Such commits DO NOT
contend for named resource locks (either on the index names or on the
IDataService
UUID
s). Since such transactions DO NOT have
dependencies outside of the specific IDataService
, a necessary
and sufficient partial order will be imposed on the executing tasks
locally by the IDataService
on which they are executing based
solely on the named resources which they declare. Without dependencies on
distributed resources, this can not deadlock.
indexLockManager
. The named index locks
are pre-declared at the start of the distributed commit protocol and are
held through both the prepare and commit phases until the end of the
commit protocol. The distributed commit must obtain a lock on all of the
necessary named index resources before proceeding. If there is an
existing commit using some of those resources, then any concurrent commit
requiring any of those resources will block. The LockManager
is
configured to require pre-declaration of locks. Deadlocks are NOT
possible when the locks are pre-declared.
A secondary partial ordering is established based on the
IDataService
UUID
s during the commit phase. This partial
order is necessary to avoid deadlocks for concurrently executing commit
phases of distributed transactions that DO NOT share named index locks.
Without a partial order over the participating IDataService
s,
deadlocks could arise because each transaction will grab an exclusive
lock on the write service for each participating IDataService
.
By ordering those lock requests, we again ensure that deadlocks can not
occur.
Note: The prepare phase for distributed commits allows the maximum possible concurrency. This is especially important as validation and merging down onto the unisolated indices can have significant length for large transactions.
The commit phase should be very fast, with syncing the disk providing the
primary source of latency. All participating indices on the participating
data services have already been checkpointed. Once the commitTime is
assigned by the DistributedTransactionService
, the group commit
need only update the root block on the live journal and sync to disk.
commitImpl
in class AbstractTransactionService
Exception
- if something else goes wrong. This will be (or will wrap) a
ValidationError
if validation fails.protected long singlePhaseCommit(AbstractTransactionService.TxState state) throws Exception
Exception
public void declareResources(long tx, UUID dataServiceUUID, String[] resource) throws IllegalStateException
DataService
s 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
.
declareResources
in interface IDistributedTransactionService
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
).IllegalStateException
public long prepared(long tx, UUID dataService) throws IOException, InterruptedException, BrokenBarrierException
TxState
. If the transaction is aborted, then throw an
InterruptedException
. Otherwise return the commitTime assigned
to the transaction.prepared
in interface IDistributedTransactionService
tx
- The transaction identifier.dataService
- The UUID
of the IDataService
which sent the
message.InterruptedException
- if the barrier is reset while the caller is waiting.IOException
- if there is an RMI problem.BrokenBarrierException
public boolean committed(long tx, UUID dataService) throws IOException, InterruptedException, BrokenBarrierException
TxState
. If the transaction is aborted, then return
false
. Otherwise return true.
Note: The TxState
will be aborted if any of the committers throws
an exception of their ITxCommitProtocol.prepare(long, long)
method.
committed
in interface IDistributedTransactionService
tx
- The transaction identifier.dataService
- The UUID
of the IDataService
which sent the
message.true
if the distributed commit was successfull and
false
if there was a problem.IOException
InterruptedException
BrokenBarrierException
protected long findCommitTime(long timestamp)
AbstractTransactionService
findCommitTime
in class AbstractTransactionService
timestamp
- The timestamp.protected long findNextCommitTime(long commitTime)
AbstractTransactionService
findNextCommitTime
in class AbstractTransactionService
commitTime
- The probe.public final void notifyCommit(long commitTime)
AbstractTransactionService
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
notifyCommit
in class AbstractTransactionService
commitTime
- The commit time.public final long getLastCommitTime()
AbstractTransactionService
IOException
.getLastCommitTime
in interface ITransactionService
getLastCommitTime
in class AbstractTransactionService
public CounterSet getCounters()
LockManager
.getCounters
in interface ICounterSetAccess
getCounters
in class AbstractTransactionService
Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.