The journal is a persistence capable data structure supporting atomic commit,
named indices, and full transactions. The
BufferMode#DiskRW mode
provides an persistence scheme based on reusable allocation slots while the
BufferMode#DiskWORM mode provides an append only persistence scheme.
Journals may be configured in highly available quorums.
This class is an abstract implementation of the
IJournal interface
that does not implement the
IConcurrencyManager,
IResourceManager, or
ITransactionService interfaces. The
Journal provides a concrete implementation that may be used for a
standalone database complete with concurrency control and transaction
management.
Limitations
The
IIndexStore implementation on this class is NOT thread-safe. The
basic limitation is that the mutable
BTree is NOT thread-safe. The
#getIndex(String) method exposes this mutable
BTree. If you
use this method to access the mutable
BTree then YOU are responsible
for avoiding concurrent writes on the returned object.
See
IConcurrencyManager#submit(AbstractTask) for a thread-safe API
that provides suitable concurrency control for both isolated and unisolated
operations on named indices. Note that the use of the thread-safe API does
NOT protect against applications that directly access the mutable
BTree using
#getIndex(String).
The
IRawStore interface on this class is thread-safe. However, this
is a low-level API that is not used by directly by most applications. The
BTree class uses this low-level API to read and write its nodes and
leaves on the store. Applications generally use named indices rather than the
IRawStore interface.
Note: transaction processing MAY occur be concurrent since the write set of a
each transaction is written on a distinct
TemporaryStore. However,
without additional concurrency controls, each transaction is NOT thread-safe
and MUST NOT be executed by more than one concurrent thread. Again, see
IConcurrencyManager#submit(AbstractTask) for a high-concurrency API
for both isolated operations (transactions) and unisolated operations. Note
that the
TemporaryStore backing a transaction will spill
automatically from memory onto disk if the write set of the transaction grows
too large.
Commit processing
The journal maintains two root blocks. Commit updates the root blocks using
the Challis algorithm. (The root blocks are updated using an alternating
pattern and "timestamps" are recorded at the head and tail of each root block
to detect partial writes. See
IRootBlockView and
RootBlockView.) When the journal is backed by a disk file, the data
are
Options#FORCE_ON_COMMIT. If
desired, the writes may be flushed before the root blocks are updated to
ensure that the writes are not reordered - see
Options#DOUBLE_SYNC.