Interface Unit
- All Superinterfaces:
AutoCloseable
Users are strongly encouraged to apply the following usage pattern:
// db of type Database or CustomDatabase, not null. // Precondition: db.info().isWritable() try (Unit u = db.openUnit()) { ... u.commit(); }where the ellipsis ('…') stands for any program code, including code that contains calls to
u.commit()
and code that repeats this usage
pattern to create one or more nested units.
The effects of so called unconfirmed write operations (see below) onto the data persisted in the database are reverted at the time a unit is closed. Those unconfirmed write operations are said to be rolled back.
To explain what an "unconfirmed write operation" is, we need to introduce some additional concepts.
A write operation that is executed within a unit u
but not within a
nested unit in u
is said to be a "write operation of u
".
A write operation w
of u
is committed in u
as soon as u.commit()
is successfully executed for the first time
since the termination of w
.
As long as w
is not committed it is said to be uncommitted.
Likewise, a nested unit in u
is committed in u
as
soon as u.commit()
is successfully executed for the first time since
that nested unit was closed.
As long as the nested unit is not committed it is said to be
uncommitted.
Note that the nested units in u
include deeply nested units,
for example, a unit u''
that is in a unit u'
thas is in
u
.
Now, an unconfirmed write operation is either an uncommitted write
operation of u
or a committed write operation of an
uncommitted nested unit in u
.
In the following examples w
denotes a write operation and c
denotes the successful execution of the commit()
method.
Unconfirmed write operations are marked with an asterisk ('*
').
Nested units in u
are indented and labeled with u'
and
u''
.
Example 1 Example 2 Example 3 u u' u'' u u' u'' u u' u'' w1 w1* w1 w2 w1.1* w1.1 w1.1 w1.1.1 w1.1.1 c c c w3 w1.1.2 c c w2.1* w1.1.1* c w2.2* c w4*In the first example the write operations
w2.1
, w1.1.1
,
w2.2
and w4
are unconfirmed because the first three ones are
committed write operations of nested units that are uncommitted in u
and the last is an uncommitted write operation of u
.
In the second example the write operations w1
and w1.1
are
unconfirmed.
(The write operation w1.1.1
was rolled back at the time u''
was closed because it was an uncommitted write operation of u''
.)
In the third example there is no unconfirmed write operation:
The write operations w1.1
, w1.1.1
and w1.1.2
were
rolled back before and w1
is a committed write operation of
u
.
Note that the write operation w1.1.1
was rolled back at the time
u'
was closed because u''
remained uncommitted in u'
.
Write operation w1.1.1
was not rolled back at the time u''
was closed because w1.1.1
was committed in u''
.
However, write operation w1.1.2
was rolled back at the time
u''
was closed because it remained uncommitted in u''
.
Units only make sense if the database is writable.
Broken Unit
A unit breaks if one of the methods specified in this interface breaks the unit or if a write operation invoked within the unit fails recording its before data.
A unit that is about to break throws a UnitBrokenException
.
In case of a disaster, for instance a power failure or a crash of the
storage device, a unit may not have a chance to throw a
UnitBrokenException
.
If a unit breaks, ACDP tries to rollback any unconfirmed write operations. However, even if the unconfirmed write operations can successfully be rolled back, the unit remains broken and units can no longer be executed.
The only way to recover from a broken unit is to close the database and open the database again.
Do the following if a unit is broken:
- Close the database.
- Check the integrity of the persisted data by calling the
ACDP.verify(java.nio.file.Path, boolean, boolean)
method. - Find out if recent changes made to the database have been
materialized, in particular, check if
forceWriteCommit
(see section "Durability" in the description of theDatabase
interface) was enabled and analyze the recorder file. (The recorder file is the place where ACDP saves any before data of unconfirmed write operations. The path to the recorder file is saved in therecFile
entry of the database layout.) - Repair the database if necessary.
- Reopen the database.
Reopening the database may rollback any unconfirmed write operations and thus healing a broken unit, however, rolling back fails if the recorder file is corrupted. If this is the case then repair the recorder file and try to open the database again.
Note that ACDP never "automatically" rolls back a unit with the exception of the situation described above. (The database has to be writable. If the database is a write protected WR database then ACDP still detects an earlier produced broken unit or a corrupted recorder file but ACDP does not execute a rollback.)
ACDP makes an effort to avoid rollbacks based on a recorder file that is, in reality, corrupted but which ACDP naively could believe being non-corrupted.
There should be no need for clients to implement this interface.
- Author:
- Beat Hörmann
-
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
Rolls back any uncommitted write operations of this unit as well as any write operations that were executed and committed in any uncommitted nested units and closes this unit.void
commit()
Commits any yet uncommitted write operations of this unit as well as any yet uncommitted nested units in this unit.
-
Method Details
-
commit
Commits any yet uncommitted write operations of this unit as well as any yet uncommitted nested units in this unit.- Throws:
ACDPException
- If this unit was originally opened in a thread different from the current thread. This exception never happens if you consequently apply the usage pattern described in the class description.UnitBrokenException
- If committing fails, including the case that this unit was already broken before this method was able to start doing its job.
-
close
Rolls back any uncommitted write operations of this unit as well as any write operations that were executed and committed in any uncommitted nested units and closes this unit.- Specified by:
close
in interfaceAutoCloseable
- Throws:
ACDPException
- If this unit was originally opened in a thread different from the current thread or if this unit contains an open read zone. This exception never happens if you consequently apply the usage pattern described in the description of this interface and if you consequently close inside a unit any read zone that was opened within that unit.UnitBrokenException
- If this unit was already broken before this method was invoked or if rolling back any uncommitted write operations failed.
-