HP OpenVMS Systems

ask the wizard
Content starts here

RMS Record Locking, File Contention?

» close window

The Question is:

     Our question concerns on a shared read access to fixed record length
 sequencial files. We use ALPHA servers 1000A and 800, operation
systems OpenVMS V7.1 and OpenVMS V7.1-1H2
respectively, programming language FORTRAN-77.
     While trying to get a shared read access to one given record in one given
 file from several (two or more) identical programs running in different
 processes the following obstacle was revealed:
- the first program to access a record reads it successfully;
- the other programs trying to get access to this very record are denied with
 an error code 52 (decimal), i.e. "RECORD LOCKED BY ANOTHER USER", even though
 the first program completed operations with this record (the other records are
 free for access).
     We partially managed to get rid of this fault adding after READ operator
 UNLOCK operator. It enabled shared access if attempts to read a record are not
 simultaneous. However attempts of multiple simultaneous access, that occures
 ocassionally, lead to
 collisions with the same error code, notwithstanding UNLOCK. Thus we were
 forced to analyze a status
word after READ operation and, in cases of errors, try reading repeatedly.
 Sometimes it leads to quite a large number of attempts until clunch prosesses
 disperse in time.
     An example of a program to demonstrate shared access collisions looks like
 this (two or more instances of this program run in separate processes
 simultaneously until all except one fall out because of the said error):
	program check_unlock
	byte buffer(1100)
C Record size is not principal and is chosen of 1100 just for example.
C File 'FILESHAR.DAT' with record length of 1100 bytes
C with arbitrary nutrition for test should be prepared beforehand:
	open(unit=10, file='FILESHAR.DAT', access='direct', shared,
     *	organization='sequential', status='old', disp='keep',
     *	form='unformatted', recordtype='fixed', recl=275)
C Infinite cycle for reading, say, of the 7-th record:
	do while(.true.)
	   read(unit=10, rec=7, iostat=istatus) buffer
          	   i=i+1		!Count of attempts
C Shutdown the cycle after collision is detected:
	   if(istatus.ne.0) then
	      type *,' Read error ', istatus,'  Attempt No ', i
	   end if
	end do
     We would greately like to know whether there is any remedy to avoid such
      Thank you for assistance,  Valentin Pisartchuk.

The Answer is :

  Your application is apparently encountering record-level contention,
  and you will need to understand the nature of this contention.  This
  contention can involve specific heavily accessed records within a file,
  or this can involve deadlocks within the application(s), or this can
  involve various other conflicting file access patterns.
  In this particular case, you will need to disable all record locks
  and maintain your own file-level and record-level access coordination,
  or manually release the record lock via explicit program request, or
  implicitly release the record lock by selecting another record in the
  file.  If you are simply reading the record, you can entirely disable
  lock acquisition (RAB$L_ROP NLK).  If writing, you can permit other
  readers but disable writers (RAB$L_ROP RLK).
  A typical pattern involves either waiting for the record lock (via
  RAB$L_ROP WAT option, and potentially adding the TMO option), or by
  periodically retrying access to the record.
  If you have no need to write to the file, you should specify READONLY
  in your OPEN statement:
	open(unit=10, file='FILESHAR.DAT', access='direct', shared,
     *	organization='sequential', status='old', disp='keep',
     *	form='unformatted', recordtype='fixed', recl=275, readonly)
  Otherwise, Fortran keeps the most recently-read record locked in
  expectation that you will then want to update it -- without
  unwittingly also overwriting another process's update.
  Some application programmers provide for an automatic release of the
  record lock (WAT and TMO options, or an explicit timer and AST), either
  via a timer that explicitly unlocks the record when the timer expires,
  or via an algorithm that reads the data and -- if a record update is
  needed -- re-reads and verifies the original contents, and then writes
  out the updated record if the original record has not changed.
  You can also use various tools to determine the cause of deadlocks,
  particularly if you have an application coded to wait for the lock
  without a timeout.  Example tools include AMDS and the Availability
  Manager, and SDA.

answer written or last revised on ( 8-MAY-2001 )

» close window