In the fall of 1999 it was discovered that the example of how to lock in the DB_File documentation, which is unfortunately also found in the Perl Cookbook, contains serious bugs.

There are two basic problems. The first is that upon opening the database, the first page is read into memory. This happens before any possibility of flocking, and if that page wound up being modified by another process before you get your lock, you can get database corruption.

The second problem is that with more recent versions of Berkeley DB the database may close and reopen the database for internal reasons. (IIRC sendmail will cause it to do this.) When you do that then you lose the flock and there is no way for you to know that this happened.

The two basic solutions are to either synchronize all of your locks through an external means (eg by flocking a semaphore file) or to use the newer BerkeleyDB module which gives you access to Berkeley DB's internal locking functions. Those not only avoid the above problems, they also allow for fine-grained locks to reduce contention betweeen programs.

For the record the fault for the bad advice rests squarely upon the folks at Sleepycat who were involved in the 1.x series of Berkeley DB. In that series they recommended grabbing the file descriptor that Berkeley DB was using and flocking that. Well it has been many years since they realized the various reasons why it was a bad idea to have people rely on such aspects of their internal behaviour, but the old bad advice just keeps on floating around...

UPDATE
I misremembered the advice being repeated in the Cookbook. It is not. However it is repeated in perlfunc's documentation for flock and hence in the Camel.

UPDATE 2
If anyone is confused by the explanation, search for "flock" in the current documentation for DB_File and read a fuller explanation.


In reply to Do not flock dbm filehandles! by tilly
in thread Locking database by tanger

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.