DB_File-Lock
view release on metacpan or search on metacpan
tie(%db_hash, 'DB_File::Lock', $db_filename, O_RDONLY, 0600, $DB_HASH, 'read') or die;
... then read the database ...
untie(%db_hash);
This is better for two reasons:
(1) Less cumbersome to write.
(2) A fatal exception in the code working on the database which does
not lead to process termination will probably not close the lockfile
and therefore cause a dropped lock.
=head1 USAGE DETAILS
Tie to the database file by adding an additional locking argument
to the list of arguments to be passed through to DB_File, such as:
tie(%db_hash, 'DB_File::Lock', $db_filename, O_RDONLY, 0600, $DB_HASH, 'read');
or enclose the arguments for DB_File in a list reference:
tie(%db_hash, 'DB_File::Lock', [$db_filename, O_RDONLY, 0600, $DB_HASH], 'read');
The filename used for the lockfile defaults to "$filename.lock"
(the filename of the DB_File with ".lock" appended). Using a lockfile
separate from the database file is recommended because it prevents weird
interactions with the underlying database file library
The additional locking argument added to the tie call can be:
(1) "read" -- acquires a shared lock for reading
(2) "write" -- acquires an exclusive lock for writing
(3) A hash with the following keys (all optional except for the "mode"):
=over 4
=item mode
the locking mode, "read" or "write".
=item lockfile_name
specifies the name of the lockfile to use. Default
is "$filename.lock". This is useful for locking multiple resources with
the same lockfiles.
=item nonblocking
determines if the flock call on the lockfile should
block waiting for a lock, or if it should return failure if a lock can
not be immediately attained. If "nonblocking" is set and a lock can not
be attained, the tie command will fail. Currently, I'm not sure how to
differentiate this between a failure form the DB_File layer.
=item lockfile_mode
determines the mode for the sysopen call in opening
the lockfile. The default mode will be formulated to allow anyone that
can read or write the DB_File permission to read and write the lockfile.
(This is because some systems may require that one have write access to
a file to lock it for reading, I understand.) The umask will be prevented
from applying to this mode.
=back
Note: One may import the same values from DB_File::Lock as one may import
from DB_File.
=head1 GOOD LOCKING ETIQUETTE
To avoid locking problems, realize that it is B<critical> that you release
the lock as soon as possible. See the lock as a "hot potato", something
that you must work with and get rid of as quickly as possible. See the
sections of code where you have a lock as "critical" sections. Make sure
that you call "untie" as soon as possible.
It is often better to write:
# open database file with lock
# work with database
# lots of processing not related to database
# work with database
# close database and release lock
as:
# open database file with lock
# work with database
# close database and release lock
# lots of processing not related to database
# open database file with lock
# work with database
# close database and release lock
Also realize that when acquiring two locks at the same time, a deadlock
situation can be caused.
You can enter a deadlock situation if two processes simultaneously try to
acquire locks on two separate databases. Each has locked only one of
the databases, and cannot continue without locking the second. Yet this
will never be freed because it is locked by the other process. If your
processes all ask for their DB files in the same order, this situation
cannot occur.
=head1 OTHER LOCKING MODULES
There are three locking wrappers for DB_File in CPAN right now. Each one
implements locking differently and has different goals in mind. It is
therefore worth knowing the difference, so that you can pick the right
one for your application.
Here are the three locking wrappers:
Tie::DB_Lock -- DB_File wrapper which creates copies of the database file
for read access, so that you have kind of a multiversioning concurrent
read system. However, updates are still serial. Use for databases where
( run in 0.854 second using v1.01-cache-2.11-cpan-e1769b4cff6 )