|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||
public interface ITransactionService
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 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.
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.
| 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 |
|---|
long newTx(long timestamp)
throws IOException
timestamp - The timestamp may be:
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
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).
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 IDataServices in an IBigdataFederation.
commitTime - The commit time.
IOException
long getLastCommitTime()
throws IOException
ITransactionService.
IOException
long getReleaseTime()
throws IOException
IOException
void declareResources(long tx,
UUID dataService,
String[] resource)
throws IOException
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.
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).
IOException
long prepared(long tx,
UUID dataService)
throws IOException,
InterruptedException,
BrokenBarrierException
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.
tx - The transaction identifier.dataService - The UUID of the IDataService which sent the
message.
InterruptedException
BrokenBarrierException
IOException - if there is an RMI problem.
boolean committed(long tx,
UUID dataService)
throws IOException,
InterruptedException,
BrokenBarrierException
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.
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
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||||