HP OpenVMS Systems Documentation
Guide to OpenVMS File Applications
|Function (Service)||FDL and RMS Options|
|Read records (Get)||ACCESS GET specified or FAB$B_FAC field FAB$V_GET set|
|Locate records (Find)||ACCESS GET specified or FAB$B_FAC field FAB$V_GET set|
|Delete records (Delete)||ACCESS DELETE specified or FAB$B_FAC field FAB$V_DEL set|
|Add new records (Put)||ACCESS PUT specified or FAB$B_FAC field FAB$V_PUT set|
|Truncate file (Truncate)||ACCESS TRUNCATE specified or FAB$B_FAC field FAB$V_TRN set|
|Modify records (Update)||ACCESS UPDATE specified or FAB$B_FAC field FAB$V_UPD set|
|Access blocks (see text)||ACCESS BLOCK_IO specified or FAB$B_FAC field FAB$V_BIO set; under certain conditions, ACCESS RECORD_IO or FAB$B_FAC FAB$V_BRO|
The record-access functions you request are compared with the protection on the specified file. If your process is limited to reading and locating records, it should have read access to the file. If your process is deleting, adding, truncating, or updating records, it must have write access to the file. RMS permits any process that may delete, add, truncate, or modify records to also locate and read records because write access to a file also implies read access.
You can perform block I/O operations using the Read, Space, and Write services. Block I/O is usually only used by applications written in VAX MACRO or other low-level languages. Note that when ACCESS BLOCK_IO is specified, the application program must also specify either SHARING USER_INTERLOCK or SHARING PROHIBIT.
Different types of record operations can be specified to define the type of access to be allowed for other processes, as shown in Table 7-2.
|Function (Service)||FDL and RMS Options|
|Read records (Get)||SHARING GET specified or FAB$B_SHR field FAB$V_SHRGET set|
|Locate records (Find)||SHARING GET specified or FAB$B_SHR field FAB$V_SHRGET set|
|Delete records (Delete)||SHARING DELETE specified or FAB$B_SHR field FAB$V_SHRDEL set|
|Add new records (Put)||SHARING PUT specified or FAB$B_SHR field FAB$V_SHRPUT set|
|Modify records (Update)||SHARING UPDATE specified or FAB$B_FAC field FAB$V_SHRUPD set|
|No access||SHARING PROHIBIT or FAB$B_SHR field FAB$V_NIL set|
|User interlocking||SHARING USER_INTERLOCK or FAB$B_SHR field FAB$V_UPI set|
|Multistreaming||SHARING MULTISTREAM or FAB$B_SHR field FAB$V_MSE set|
If other processes are limited to reading and locating records, they are unable to modify or add records, and record-lock checking is not performed. If other processes are allowed to delete, add, or modify records, they can also read records; however, record-lock checking occurs. All record-access functions use interlocked interprocess file sharing.
No access denies access to all accessors except the accessor who specifies the option. This option might be used when a file is shared infrequently or when doing a major update. When you use this option, be sure to close the file promptly when other users are trying to access the file. Choose this option or the user-interlocking option when using block access. To use the Queue I/O Request system service, specify the FILE USER_FILE_OPEN attribute (FAB$L_FOP field FAB$V_UFO set). The no-access option does not allow file sharing and requires that your process have write file protection access.
User interlocking permits the user to maintain interlocking protection (including maintaining the end-of-file mark). For any other form of file sharing, RMS controls the reading and writing of I/O buffers to ensure the integrity of file and record structures. This option is useful for nonshared sequential files and for block I/O access using RMS or the Queue I/O Request system service.
Multistreaming allows your process to access the same file using more than one record stream and allows other users to access the file using interlocked interprocess file sharing (unless SHARING PROHIBIT is also specified). When you select this option, select the appropriate SHARING record operations, such as SHARING GET. When multiple streams are connected, the buffers allocated for each stream become part of a buffer cache for the entire process. (A buffer cache is a common shared buffer pool intended to minimize I/O.) A record operation on one stream may use cached buffers from a previous record operation on a different stream that referenced the same buckets.
When you open or create a file, you must specify the file access and file sharing you want for it. When using FDL or RMS, the default is to read records from the file (ACCESS GET) and to allow others accessors to read records from the file (SHARING GET). Typically, an application program may want to read records (ACCESS GET) while allowing other accessors to add records (SHARING PUT). You might want to modify records (ACCESS UPDATE) while allowing other accessors to add new records to the file (SHARING PUT).
When you create a file, the default is for FDL and RMS to add records to the file (ACCESS PUT) and to not allow others to access the file (SHARING NONE). When you create a file with the create-if option, it is especially important to specify the access and sharing values. In this instance, you have denied yourself access if the file already exists because you have specified SHARING NONE and you are not the initial accessor. One way to avoid this when you create a file is to allow most operations for other users (such as SHARING GET, SHARING PUT, SHARING UPDATE, and SHARING DELETE).
Combinations of file access and file sharing that specify a mixture of
interlocked interprocess file access and user-interlocked interprocess
file sharing allow the application program to access the file without
record locking protection. Such combinations are not recommended for
general use; they should be used only for application programs that
require read-only access to a file. Other combinations may cause an
error, such as requesting ACCESS BLOCK_IO without specifying SHARING
NONE or SHARING USER_INTERLOCK.
7.1.2 Interlocked Interprocess File Sharing
Interlocked interprocess is the most common form of file sharing. This method allows the connection of one or more record streams (RABs) to one or more processes (FABs), either within a single process or across several processes. When using this form of file sharing, the values specified for file sharing and file access by the initial accessor determine the type of access permitted for subsequent processes.
The initial accessor must consider the restrictions that result from the values specified for file sharing and file access. Typically, the initial accessor denies all write access to subsequent processes. Such a restriction occurs when the initial accessor specifies some type of write access for file access without specifying write access for file sharing.
If the initial accessor specifies read-only file access and file sharing, subsequent accessors can only read the file. If the appropriate type of write access is not specified, then subsequent accessors cannot perform the corresponding write operations to the file.
If the initial accessor specifies one or more values for file sharing, subsequent processes can access the file if they specify compatible file access values. For example, if the initial accessor specifies SHARING GET and SHARING PUT, subsequent accessors must specify ACCESS GET to read the file, and ACCESS PUT to write new records to the file (read access is implied by all four types of write access).
Table 7-3 presents the values that the initial accessor of a file can specify for file sharing to permit access to subsequent accessors.
|Initial Accessor Sharing||Subsequent Accessor Access|
|SHARING PROHIBIT||No access allowed|
|SHARING GET 1||ACCESS GET 1|
|SHARING DELETE||ACCESS DELETE|
|SHARING PUT||ACCESS PUT|
|SHARING UPDATE||ACCESS UPDATE|
Because the initial accessor can specify multiple SHARING values, a subsequent accessor whose ACCESS values match one, some, or all of the initial accessor's SHARING values is allowed access; however, when the subsequent accessor specifies an ACCESS value that the initial accessor did not specify as a SHARING value (an exception is SHARING GET, which is implied), access is denied to the subsequent accessor.
In addition to comparing the file access values that subsequent accessors specify with the file-sharing values specified by the initial accessor, the values that subsequent accessors specify must be compatible with values specified by the initial accessor. Table 7-4 shows the file-sharing values that subsequent accessors must specify to access the file.
|Initial Accessor Access||Subsequent Accessor Sharing|
|ACCESS GET 1||SHARING GET 1|
|ACCESS DELETE||SHARING DELETE|
|ACCESS PUT||SHARING PUT|
|ACCESS UPDATE||SHARING UPDATE|
Because the initial accessor can specify multiple ACCESS values, a
subsequent accessor whose SHARING values match all of the initial
accessor's ACCESS values is allowed access; however, when the
subsequent accessor specifies a SHARING value that the initial accessor
did not specify as an ACCESS value (an exception is ACCESS GET, which
is implied), access is denied.
7.1.3 User-Interlocked Interprocess File Sharing
User-interlocked interprocess file sharing allows one or more application programs to write records to a sequential file residing on a disk device or to a file on a disk device that is open for block I/O processing. It cannot be used with relative and indexed files opened for record access. (For record access to relative and indexed files, RMS transparently controls the reading and writing of buffers to the file and always maintains current end-of-file information.)
All sequential files that reside on disk devices may be write shared with user-provided interlocks. To use this feature, you must specify SHARING USER_INTERLOCK (set the FAB$B_SHR field FAB$V_UPI bit). Note that when this option is specified, RMS does not attempt to control the reading and writing of I/O buffers across processes, nor does it maintain end-of-file information. Thus, you must use the Flush service (or language equivalent, if any) to force the writing of modified I/O buffers and to rewrite the record attributes (including end-of-file information) in the file header. Processes that open the file after that point obtain the new end-of-file information. Note also that record attributes are rewritten whenever a file is closed. The last write accessor to close the file must also be the last accessor to have extended the file. If not, end-of-file information is written by another write accessor. Read accessors of a shared sequential file can update their internal end-of-file context by closing and reopening the file.
No form of record locking is supported for this type of file sharing. Although record locking is not checked using user-interlocked interprocess file sharing, file locking is checked. For instance, if you or another user specify SHARING NONE, one of you may be denied access.
If a process tries to implement the truncate service when closing a sequential file, it must have sole write access to the file. If other processes have write access to the file, RMS does not close it and it remains accessible to other processes. If other processes have the file open for read access, RMS defers the truncation until the final process having read access closes the file.
Similarly, if a process tries to implement the truncate-on-put option
when inserting a record into a sequential file, it must have
sole access to the file. If other processes have access to the file,
RMS does not insert the record.
7.2 Record Locking
Synchronized access to records is required in a shared file environment where record streams may compete for access to records. The operating system implements synchronized access using record locking. That is, record access conflicts are resolved by locking the record until the final competing record stream processes the record. This ensures that a program may add, delete, or modify records without interference and that when a record operation is finished, the data is consistent.
On VAX systems, RMS record locking differs from RMS Journaling for OpenVMS record locking. If your application program uses Recovery Unit Journaling, see the RMS Journaling for OpenVMS Manual for details.
The operating system allows you to determine whether the application program or RMS provides record locking. Processes accessing the file make this choice by specifying appropriate sharing attributes and access attributes in the FAB as described in Section 7.1. In general, RMS enables record locking when record modifications are permitted in a shared file environment.
RMS provides record locking for all file organizations and uses the
lock manager to keep conflicting record streams from updating a record
simultaneously. The rest of this section describes record locking.
7.2.1 Default Record Locking
You can specify various record-locking options in the RAB when you access a record by way of a record stream. If you do not explicitly specify any record-locking options when you access a record, RMS uses default record locking to automatically and transparently lock and unlock shared records. Default record locking does not require special handling of locks in the application program.
In a typical record-locking scenario, an application program calls a service to access and lock a record. The application program then processes the locked record. When it finishes processing the record, the application program calls the appropriate service to finish processing and unlock the record.
The following scenario illustrates processing an existing record:
When RMS provides record locking, the Get, Find, and Put services apply locks. The Get service and the Find service normally return with a record locked, but the Put service returns with the record unlocked unless you specify the manual-unlocking option.
When the application program uses default record locking, RMS automatically unlocks the locked record when one of the following events occurs: