Ken Williams


Tie::DB_Lock - ties hashes to databases using shared and exclusive locks


 use Tie::DB_Lock;
 use DB_File;
 tie(%hash, 'Tie::DB_Lock', $filename, 'rw');  # Open for writing
 $hash{'key'} = 'value';
 untie %hash;
 tie(%hash2, 'Tie::DB_Lock', $filename); # Default is read-only
 print("Value is $hash2{'key'}\n");
 untie %hash;


This is a front-end for the DB_File package.

If you tie a hash in read-only mode, this module puts a shared lock on the database file, copies it to a temporary file, unlocks the original database, and then ties the tempfile using DB_File.

If you tie the hash in read-write mode, we put an exclusive lock on the database and tie it directly using DB_File.

The reason I copy the whole file every time I read from it is that this allows the program to read from the file for as long as it wants to, without interfering with other people's writes. This works well if you typically have long, sustained reads, and short, bursty writes. See the README file for help in deciding whether you want to use this package.

You don't always need to call untie() explicitly - it will be called for you when %hash goes out of scope. And if all goes as planned, you'll never know the temporary file ever existed, since it will evaporate when %hash goes away.


  • $Tie::DB_Lock::TEMPDIR

    You can specify the directory in which to place the temporary files that get created when you open a database for read-only access. To do so, set the variable $Tie::DB_Lock::TEMPDIR to the directory you want to use. You may get the best results if your temporary directory resides on the same disk (or filesystem) as your databases.

  • $Tie::DB_Lock::WAIT_TIME

  • $Tie::DB_Lock::RETRIES

    By default, DB_Lock will try once every second for fifteen seconds to put locks on the things it's trying to lock. After that it will give up. Change the number of seconds between attempts by setting the value of $Tie::DB_Lock::WAIT_TIME (must be an integer), and change the number of attempts by setting the value of $Tie::DB_Lock::RETRIES.

  • $Tie::DB_Lock::VERBOSE

    If you think something funny is going on with your database and you want to watch the locking process happening, you can set the variable $Tie::DB_Lock::VERBOSE to a true value. A bunch of diagnostic messages will get printed to STDERR.

  • $Tie::DB_Lock::TIEPACK

    Don't change this unless you're sure. If you change it, DB_Lock will use a different back-end database TIEHASH package instead of DB_File. Any database you want to use must reside entirely in a single file so that it can be locked properly and copied to the temporary directory. Support for other database formats should be considered experimental.


Whenever a tie() fails because a lock blocked your access, tie() will return the undefined value. CHECK THE RETURN VALUE from tie()!

  tie(%hash, 'Tie::DB_Lock', $file, 'rw') or die $!;

If you don't check the return value, you'll probably continue on your merry way, thinking that you opened the database when in fact you didn't.


Deadlock is rare, but it's awful when it happens.

If each process wants more than one DB file before it can start work, and processes do not all ask for their DB files in the same order, and the processes write, then there's a risk of deadlock. The simplest case is that process 1 wants files A and B and holds A, and process 2 wants A and B and holds B. Neither process can get what it needs, and they both wait forever. To avoid this, do one of the following: (1) Have all processes open DB files in the same order, first A, then B. (2) Use a special locking or coordination scheme.

Deadlock can happen pretty much whenever you're using locks on a resource.


Maybe change from using FileHandle to IO::File? Benchmarks involved.

Allow other database back-ends than DB_File.


Ken Williams

Copyright (c) 1998 Ken Williams. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


perl(1), perltie(1), perlfunc(1), DB_File(3)