public interface ITransactionService extends ITimestampService
An interface for managing transaction life cycles.
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.
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 IDataService
s 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.
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.
Modifier and Type | Method and Description |
---|---|
void |
abort(long tx)
Request abort of the transaction write set.
|
long |
commit(long tx)
Request commit of the transaction write set.
|
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. |
nextTimestamp
destroy, getHostname, getServiceIface, getServiceName, getServiceUUID
long newTx(long timestamp) throws IOException
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.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.long commit(long tx) throws ValidationError, IOException
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).
tx
- The transaction identifier.ValidationError
- if the transaction could not be validated.IllegalStateException
- if tx is not an active transaction.IOException
- RMI errors.void abort(long tx) throws IOException
tx
- The transaction identifier.IllegalStateException
- if tx is not an active transaction.IOException
- RMI errors.void notifyCommit(long commitTime) throws IOException
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 IDataService
s in an IBigdataFederation
.
commitTime
- The commit time.IOException
long getLastCommitTime() throws IOException
ITransactionService
.IOException
long getReleaseTime() throws IOException
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.)
IOException
Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.