Oberon || Library || Module Index || Search Engine || Definition || Module


Ulm's Oberon Library:
TransStreams


NAME

TransStreams - transactions on streams

SYNOPSIS

CONST last = 0; prior = 1; current = 2;
TYPE State = SHORTINT; (* last..current *)
CONST standard = 0; auto = 4; read = 8;
TYPE Mode = SHORTINT;
   (* additive combination of standard, auto, read, last and prior *)


TYPE Stream = POINTER TO StreamRec; TYPE StreamRec = RECORD (Streams.StreamRec); END;

(* errors at opening time *) CONST illegalParam = 0; CONST bufferedStream = 1; CONST badMagic = 2; CONST noLegalState = 3; CONST corruptedFile = 4; CONST cannotAccessFile = 5; (* invalid usage *) CONST illegalPos = 6; CONST nestedCall = 7; CONST noPriorState = 8; CONST noTransactionRunning = 9; CONST readOnly = 10; CONST transactionInProgress = 11; CONST alreadyClosed = 12; (* troubles with the underlying stream *) CONST cannotAccessSysPages = 13; CONST cannotUpdateSysPages = 14; CONST cannotAccessContents = 15; CONST cannotUpdateContents = 16; CONST recoveringDueToFailure = 17; CONST closeFailed = 18; CONST errorcodes = 19; TYPE ErrorCode = SHORTINT; TYPE Event = POINTER TO EventRec; TYPE EventRec = RECORD (Events.EventRec); errcode: ErrorCode; END; VAR error: Events.EventType; VAR errormsg: ARRAY errorcodes OF Events.Message;

PROCEDURE Open(VAR s: Streams.Stream; base: Streams.Stream; mode: Mode; errors: RelatedEvents.Object) : BOOLEAN;

(* transaction primitives *) PROCEDURE Begin(s: Streams.Stream) : BOOLEAN; PROCEDURE Abort(s: Streams.Stream) : BOOLEAN; PROCEDURE Commit(s: Streams.Stream) : BOOLEAN; (* transaction shorthands *) PROCEDURE Touch(s: Streams.Stream) : BOOLEAN; (* Commit & Begin *) PROCEDURE Forget(s: Streams.Stream) : BOOLEAN; (* Abort & Begin *)

PROCEDURE Switch(s: Streams.Stream) : BOOLEAN; PROCEDURE Toggle(s: Streams.Stream) : BOOLEAN; PROCEDURE Available(s: Streams.Stream; state: State) : BOOLEAN;

PROCEDURE GetInfo(s: Streams.Stream; state: State; VAR info: ARRAY OF BYTE) : BOOLEAN; PROCEDURE SetInfo(s: Streams.Stream; info: ARRAY OF BYTE) : BOOLEAN;

PROCEDURE SetPoolSize(s: Streams.Stream; no: INTEGER) : BOOLEAN; PROCEDURE GetPoolSize(s: Streams.Stream; VAR no: INTEGER) : BOOLEAN; PROCEDURE GetEffPoolSize(s: Streams.Stream; VAR no: INTEGER) : BOOLEAN; PROCEDURE SetNoBufs(no: INTEGER) : BOOLEAN; PROCEDURE GetNoBufs(VAR no: INTEGER) : BOOLEAN; PROCEDURE GetEffNoBufs(VAR no: INTEGER) : BOOLEAN;

DESCRIPTION

TransStreams (transaction streams) offers a local transaction concept (see ObjectTransactions) on stream level. Objects of type Stream are extensions of Streams.Stream with read, write, seek, tell and trunc capabilities but support transactions as well. A transaction in the sense of this module represents a frame for an arbitrary number of write operation executed on the stream. These operations do not alter the stream contents until the transaction is successfully committed. In any other cases, namely if the transaction is explicitely aborted or if the program terminates before a transaction was committed, the contents of a transaction stream remains unaffected. This holds true even if a program terminates for any reason while a commit operation itself is in progress. Since either all or none of the contents changes applied to the stream during a transaction become valid, committing a transaction can be seen as an atomar operation which transfers the stream from one consistent state into another.

A transaction stream can hold up to three states:

current
refers to the transaction currently in progress and is not available if no transaction is active.
last
reflects the contents of the stream at the time of the last successful commit. This state is always available.
prior
stores the last but one successfully committed transaction. Only available if no error occured during the last two commit operations.

A transaction stream behaves like any other regular stream except that write operations must be executed within the scope of a transaction. After a transaction is aborted or when the stream is reopened, a consistent state is restored from the contents of the stream base given as an argument to Open. Base streams must be unbuffered and support read, write, seek and tell operations, and holes. They are used by TransStreams to store data permanently and will therefore typically be of type UnixFiles.File. Note that the termination of the base stream is propagated to the transaction stream (see Resources).

The parameter mode provided to Open is a combination (sum) of a state and an operation mode. Any senseful sum of the following constants may be used:

standard
open a stream with standard capabilities, i.e. the application is responsible for beginning any transaction.
read
open a transaction stream for read only access. Any attempt to begin a transaction will be rejected. No write operation at all will be performed on base.
auto
implicitely starts a transaction during the opening process. The transaction will be committed automatically when Streams.Close is called.
last
The next transaction will start from the state associated with the last successful transaction. This is the default behaviour.
prior
If available, the last and the prior state are toggled (see below). The next transaction will start from the state associated with last but one successful transaction. If used in combination with standard or auto this switch becomes permanent, even if no transaction is executed later on. Combined with read any read operation will return data from the prior rather than the last state, but this effect is temporary.

On a read-only stream, read, tell or seek operations are always possible. In any other case any attempt to operate on a stream with no transaction in progress will fail. Thus, if not opened in auto mode, a transaction has to be started explicitly before the stream is accessible through the interface of Streams. Transactions may be controlled by Transactions on base of ObjectTransactions, or by means of the following procedures, which are available for all streams regardless of whether they have been opened in auto mode or not.

Begin
Start a transaction on stream s using the contents associated with the state last as origin.
Commit
Commit a previously started transaction and store any contents changes permanently in the underlaying base stream of s and associate it with the state last. The former last state will become the new prior one, while the former prior state is discarded.
Abort
Abort the current transaction and reset s to the state valid before the transaction was begun, i.e. to the last consistent state.
Toggle
Toggle the states last and prior permanently. This operation is implicitely executed when the stream is opened with mode set accordingly. The procedure will fail, if a transaction is in progress, a stream is opened readonly or no prior state is available.
Switch
Temporarily switch the states last and prior. The next transaction will use the contents of the last but one successfully committed transaction as its starting point. The procedure will fail, if a transaction is in progress or a prior state is not available. For streams opened with mode = read + prior this operation is performed implicitely during the opening process. It will fail, if no prior state exists.
Touch
is equivalent to Commit + Begin.
Forget
is equivalent to Abort + Begin.

Toggle and Switch can be utilized to implement an undo command for transaction streams (see section examples), which discards the effect of the last successful transaction.

Since TransStreams can guarantee only the existence of one consistent state, Available should be used to check if a certain state exists.

Other than an internal enumeration TransStreams does not store any information about transactions. Instead, it offers a SetInfo procedure which associates an array of bytes with the current transaction. While SetInfo requires a transaction to be in progress, previously stored information can be obtained by GetInfo even if no transaction is running. According to state, GetInfo returns the information associated with the current transaction (if in progress), the last successfully commited transaction (which is always available) or a prior transaction (presumed the corresponding state is still accessible).

The size of info is restricted to an implementation-dependent value (about 8K in the current version).

Read and write operation on a transaction stream are buffered. To prevent programs from consuming to much memory and to reduce swapping or/and paging activity of the associated processes applications might want to control the size of the internal buffer pools. For this reason, the following procedures are provided:

SetPoolSize
Make no the maximum number of internal buffers to be used by s.
SetNoBufs
Limit the total number of internal buffers used by all transaction streams to no.

However, TransStreams will ignore the limits if more space is required to buffer write operations. In these cases, reduction of the internal pool size is delayed until the next commit or abort operation takes place. GetEffPoolSize and GetEffNoBufs return the effective number of buffers currently in use, while GetPoolSize and GetNoBufs return the default settings as defined by means of SetPoolSize or SetNoBufs.

DIAGNOSTICS

All procedures return FALSE in case of an error and will raise an event of the type error to the affected stream. During the opening process error events are related to the parameter errors. Note that the error events of the underlying stream are forwarded to the associated transaction stream. Following error codes may be returned by TransStreams:
illegalParam
An invalid mode was given to Open.
bufferedStream
The base stream passed to Open must not be buffered.
badMagic
TransStreams did not find its magic number at the beginning of the underlying stream. Probably, it is not a file which has been created earlier by (this version of) TransStreams.
noLegalState
Neither of the two possible states in the underlying stream was found to be consistent. Probably, the file has been corrupted by external sources.
corruptedFile
The system pages were not available at opening time.
cannotAccessFile
This error code is returned by Open if some basic stream operations on the underlying stream fail.
illegalPos
An invalid position was given to a seek or trunc operation of Streams.
nestedCall
There may be only one operation running on a transaction stream concurrently.
noPriorState
This error code may be returned by Toggle or Switch when there is no other consistent state available.
noTransactionRunning
Stream operations (read, write, seek, tell and trunc) are valid only during a transaction (the only exception are read-only opened transaction streams). Further, Abort, Commit, Forget, SetInfo, and Touch may be called only while a transaction is in progress.
readOnly
This error code is returned by all updating operations if the stream has been opened in read-only mode.
transactionInProgress
Begin, Switch, and Toggle return this error code if there is an already running transaction.
alreadyClosed
An operation was tried on an already closed transaction stream.
cannotAccessSysPages
Accesses to the system pages on the underlying stream failed.
cannotUpdateSysPages
Updates of the system pages on the underlying stream failed.
cannotAccessContents
Accesses to the visible pages on the underlying stream failed.
cannotUpdateContents
Updates of the visible pages on the underlying stream failed.
recoveringDueToFailure
A commit operation failed due to some reason (see additional error events) which caused the current transaction to be aborted.
closeFailed
The final close operation failed. This shouldn't be a fatal error, however, since the underlying stream is unbuffered, i.e. all changes are already done.

TransStreams has several assertions, some of them may fail in case of invalid usage:

EXAMPLES

Open a transaction stream stream in auto mode and store the data in file name:

Open a transaction stream in non-auto mode and execute two transactions on it:

Implement an undo command, which resets the stream to a consistent state prior to the last successful transaction:

SEE ALSO

ObjectTransactions
transactions which involve one object only
RelatedEvents
error handling
Streams
stream operations
Transactions
general abstraction for transactions
UnixFiles
stream implementation of UNIX files

AUTHOR

Werner Stanglow (stanglow@mathematik.uni-ulm.de),
minor revisions due to Andreas Borchert
Edited by: borchert, last change: 1996/11/28, revision: 1.6, converted to HTML: 1997/04/28

Oberon || Library || Module Index || Search Engine || Definition || Module