Copyright | (c) 2015 Călin Ardelean |
---|---|
License | MIT |
Maintainer | Călin Ardelean <calinucs@gmail.com> |
Stability | experimental |
Portability | portable |
Safe Haskell | None |
Language | Haskell2010 |
Extensions |
|
Transaction
evaluation inside MonadIO
.
- newtype Transaction l m a = Transaction {
- unTransaction :: StateT (TransactionState l) m a
- data TransactionState l = TransactionState {
- transHandle :: !(Handle l)
- transId :: !TransactionId
- transReadList :: ![DocumentKey]
- transUpdateList :: ![(LogRecord, ByteString)]
- runQuery :: (MonadIO m, LogState l) => Handle l -> Transaction l m a -> m (Either TransactionAbort a)
- data TransactionAbort
- commitThread :: LogState l => Handle l -> Bool -> IO ()
Documentation
newtype Transaction l m a Source
Abstract monad for writing and evaluating queries under ACID semantics.
The l
parameter stands for a LogState
backend, m
is a MonadIO
that gets
lifted, so users can run arbitrary IO inside queries, and a
is the result.
Transaction | |
|
Monad m => Monad (Transaction l m) Source | |
Functor m => Functor (Transaction l m) Source | |
Monad m => Applicative (Transaction l m) Source | |
MonadIO m => MonadIO (Transaction l m) Source |
data TransactionState l Source
State held inside a Transaction
.
TransactionState | |
|
runQuery :: (MonadIO m, LogState l) => Handle l -> Transaction l m a -> m (Either TransactionAbort a) Source
Transaction
evaluation inside a MonadIO
.
Lookups are executed directly, targeting a specific version (TransactionId
)
, while the keys of both read and written documents are collected in the
TransactionState
.
At the end various consistency checks are performed, and the transaction is
aborted in case any fails. See TransactionAbort
for details.
Otherwise, under master lock, space in the data (abstract) file is allocated
with alloc
, and the transaction records are written in the
logPend
, and also in the log file, with logAppend
.
Writing the serialized data to the data file, updating indexes and completing
the transaction is then left for the commitThread
.
Note that transactions are only durable after commitThread
finishes.
In the future we may add a blocking version of runQuery
.
data TransactionAbort Source
Error returned by runQuery
for aborted transactions.
It is an instance of Exception
solely for user convenience,
as the database never throws it.
AbortUnique String | Returned when trying to update an |
AbortConflict String | Returned when there is a conflict with concurrent transactions.
This happenes when the The second part could be relaxed in the future based on a user policy, since overwriting updates are sometimes acceptable. |
AbortDelete String | Returned when trying to delete a document that is still referenced by other documents. TODO: Current implementation is not completely safe in this regard, as updates should also be checked. The reason is that the check is performed on indexes and on the pending log. So there is a small window in which it is possible for a concurrent transaction to update a record deleted by the current one, before adding it to the pending log, without any error. |
commitThread :: LogState l => Handle l -> Bool -> IO () Source
Code for the commit thread forked by open
.
It periodically checks for new records in the logPend
, and processes them,
by adding a Completed
record to the log file with logAppend
, and
updating indexes with updateMainIndex
, updateFilterIndex
, updateSortIndex
and
updateUniqueIndex
, after writing (without master lock) the serialized documents
in the data file with writeDocument
.
It also moves the records from logPend
to logComp
.