#set TITLE = "table locking"
#include top

.SH Table write and table read locking
\fBshsql\fR provides table write locking and table read locking, which are
described below.  \fBshsql\fR also provides
#set FILE = "recordlocking.html"
#set TAG = "record locking"
#include link
which is somewhat different in that it is under programmer control; it is
discussed on its own manual page.
.LP
All types of \fBshsql\fR locking are "advisory", meaning that they are a convention
that "obedient" processes adhere to.  Any process that uses the shsql API for
database access is "obedient".  For example, if a shsql process gets a
write-lock on a table, another shsql process will respect this and refrain from
writing to the table, but other non-shsql processes will not be prevented (eg. by the 
operating system) from writing.

#include space

.SH Write locking
In order to insure that only one \fBshsql\fR process can update a certain table
at any one point in time, table "write-locking" is done.  During normal operation
tables are write-locked only for the short amount of time that it takes to actually
write the update to the table.  However, certain activities such as
#set FILE = "maint.html"
#set TAG = "table cleaning / index rebuild"
#include link
and
#set FILE = "tables.html#edit"
#set TAG = "manual editing of data files"
#include link
cause tables to be write-locked for longer periods of time.
.LP
A \fBshsql\fR process may write-lock no more than one data file at a time.
.LP
There are no restrictions on reading from a write-locked table.
.LP
Write locks are obtained by opening a file in the \fClocks\fR directory
called \fItablename\fC.wlock\fR and then using fcntl(2) to gain exclusive access
to that file.  To release the lock, exclusive access is released via fcntl(2).
The file generally remains, but if removed, the next process to issue a
write lock will create a new one.
.LP
When one process wants to update a data file and finds it write-locked, 
it retries several times. After 
#set FILE = "config.html#dbwritelock_ntries"
#set TAG = "some number of failed tries"
#include link
the attempt is aborted with an error (error code# 9).

#include space
.ig >>
<a name=readlock></a>
.>>

.SH Read locking

During some administrative activities that radically modify a data file, such as
#set FILE = "maint.html"
#set TAG = "table cleaning / index rebuild,"
#include link
#set FILE = "dataedit.1.html"
#set TAG = "manual editing,"
#include link
or use of the
#set FILE = "alter.html"
#set TAG = "ALTER command,"
#include link
table "read-locking" is done, to prevent all \fBshsql\fR processes from accessing
invalid data.  
Since all of these activities work in a separate temp file copy, 
the read lock is only held for the brief time that it takes to replace
the original data file with the modified copy.
.LP
When a process wants to read from a data file and finds it read-locked by someone else,
it waits (indefinitely) until the readlock file is gone, at which time it resumes.
Thus, holders of read locks must minimize the time that any one table is
tied up, and if a read-locking activity seems to end abnormally, make sure
that the \fC.readlock\fR file is removed.
.LP
A read lock is obtained by creating a file in the data directory
called \fItablename\fC.readlock\fR.  This is followed by a short wait to allow any
in-progress reads to finish.
The read lock is released by removing the file.  \fBshsql\fR programs that need to 
set a read-lock will exit without doing anything if a readlock file already exists 
for the table of interest.

#include bottom
