DB_File::Lock - Locking with flock wrapper for DB_File
use DB_File::Lock; use Fcntl qw(:flock O_RDWR O_CREAT);
$locking = "read"; $locking = "write"; $locking = { mode => "read", nonblocking => 0, lockfile_name => "/path/to/shared.lock", lockfile_mode => 0600, };
[$X =] tie %hash, 'DB_File::Lock', $filename, $flags, $mode, $DB_HASH, $locking; [$X =] tie %hash, 'DB_File::Lock', $filename, $flags, $mode, $DB_BTREE, $locking; [$X =] tie @array, 'DB_File::Lock', $filename, $flags, $mode, $DB_RECNO, $locking;
# or place the DB_File arguments inside a list reference: [$X =] tie %hash, 'DB_File::Lock', [$filename, $flags, $mode, $DB_HASH], $locking;
...use the same way as DB_File for the rest of the interface...
When you need locking, simply use this module in place of DB_File and add an extra argument onto the tie command specifying if the file should be locked for reading or writing.
The alternative is to write code like:
open(LOCK, "<$db_filename.lock") or die; flock(LOCK, LOCK_SH) or die; tie(%db_hash, 'DB_File', $db_filename, O_RDONLY, 0600, $DB_HASH) or die; ... then read the database ... untie(%db_hash); close(LOCK);
This module lets you write
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.
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''):
Note: One may import the same values from DB_File::Lock as one may import from DB_File.
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.
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 reads may be lengthy and consistency problems may occur.
Tie::DB_LockFile --- DB_File wrapper that has the ability to lock and unlock the database while it is being used. Avoids the tie-before-flock problem by simply re-tie-ing the database when you get or drop a lock. Because of the flexibility in dropping and re-acquiring the lock in the middle of a session, this can be massaged into a system that will work with long updates and/or reads if the application follows the hints in the POD documentation.
DB_File::Lock (this module) --- extremely lightweight DB_File wrapper that simply flocks a lockfile before tie-ing the database and drops the lock after the untie. Allows one to use the same lockfile for multiple databases to avoid deadlock problems, if desired. Use for databases where updates are reads are quick and simple flock locking semantics are enough.
(This text duplicated in the POD documentation, by the way.)
Helpful insight from Stas Bekman <stas@stason.org>
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |