Lock(3pm)
π Lock(3pm) π
okay bestie, welcome to the Lock page from the User Contributed Perl Documentation collection β this one's all about DB_File::Lock, and it's genuinely iconic. let's get into it π«Ά
β¨ NAME β¨
DB_File::Lock β a flock wrapper that gives you locking for DB_File π
πΈ SYNOPSIS πΈ
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...
π¦ DESCRIPTION π¦
So basically, this module is a wrapper for the DB_File module, and what it adds is locking. periodt.
When you need locking, you literally just use this module instead of DB_File and you tack on one extra argument onto the tie command that says whether the file should be locked for reading or for writing. that's the whole vibe π₯
The alternative β the long way, the no-thanks way β is writing code like this:
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);
But with this module you get to write:
tie(%db_hash, 'DB_File::Lock', $db_filename, O_RDONLY, 0600, $DB_HASH, 'read') or die;
... then read the database ...
untie(%db_hash);
and honestly? this is better for two reasons, no cap:
- It's less cumbersome to write. β¨
- If a fatal exception happens in the code working on the database, and that exception doesn't lead to the process terminating, then it will probably not close the lockfile β which therefore causes a dropped lock. π (this is the whole reason locking wrappers are a thing, bestie β never roll your own if you can avoid it.)
π USAGE DETAILS π
To tie to the database file, you just add an extra locking argument onto the list of arguments that get passed through to DB_File, like so:
tie(%db_hash, 'DB_File::Lock', $db_filename, O_RDONLY, 0600, $DB_HASH, 'read');
or you can enclose the arguments for DB_File in a list reference instead:
tie(%db_hash, 'DB_File::Lock', [$db_filename, O_RDONLY, 0600, $DB_HASH], 'read');
The filename used for the lockfile defaults to "$filename.lock" β that's the filename of the DB_File with ".lock" appended, iykyk. Using a lockfile that's separate from the database file is recommended, because it prevents weird interactions with the underlying database file library. π§
So that extra locking argument you add to the tie call can be any of these three things:
"read"β acquires a shared lock for reading π"write"β acquires an exclusive lock for writing π₯- A hash with the following keys (all of them optional except for the
"mode"):
modeβ the locking mode, either"read"or"write".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.nonblockingβ determines if theflockcall on the lockfile should block waiting for a lock, or if it should return failure if a lock can't be immediately attained. If"nonblocking"is set and a lock can't be attained, thetiecommand will fail. Currently, I'm not sure how to differentiate this between a failure from theDB_Filelayer. πlockfile_modeβ determines the mode for thesysopencall in opening the lockfile. The default mode will be formulated to allow anyone that can read or write theDB_Filepermission 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.
Note: One may import the same values fromDB_File::Lockas one may import fromDB_File. π
π GOOD LOCKING ETIQUETTE π
Okay so, to avoid locking problems, you need to realize this one crucial thing: it is critical that you release the lock as soon as possible. Think of 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. fr fr.
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 β and this one's important β realize that when you're 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 one has locked only one of the databases, and cannot continue without locking the second. Yet that second one 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. π
β 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. So it is therefore worth knowing the difference, so that you can pick the right one for your application. main character energy, honestly.
Here are the three locking wrappers:
Tie::DB_Lockβ aDB_Filewrapper 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β aDB_Filewrapper 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) β an extremely lightweightDB_Filewrapper 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.) π«Ά
π AUTHOR π
David Harris <dharris@drh.net>
Helpful insight from Stas Bekman <stas@stason.org>
π SEE ALSO π
and that's the whole page, bestie!! π this was perl v5.36.0, dated 2022-10-13 β go forth and lock responsibly, and remember: hot potato. π₯π
β¨
π¦ where this page comes from
- ubuntu noble: libdb-file-lock-perl 0.05-6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libdb-file-lock-perl 0.05-6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libdb-file-lock-perl 0.05-6 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms