Здравствуйте, коллеги!
Для монопольной блокировки DBM файлов до настоящего
времени я пользовался известным "классическим" приемом,
основанным на flock() и предлагаемым в различной литературе
(в том числе в книгах Camel book и Perl Cookbook):
use MLDBM qw(DB_File);
use Fcntl qw(:DEFAULT :flock);
...
$db=tie(%db, \'MLDBM\', $file, O_RDWR) || die $!;
$fd=$db->fd;
open(DB_FH, "+<&=$fd") || die $!;
flock (DB_FH, LOCK_EX) || die $!;
$db{$key}=$reference;
$db->sync;
undef $db;
untie %db;
close(DB_FH);
...
Однако, пытаясь более глубоко разобраться в вопросах
блокировки DBM файлов, я обнаружил ряд важных, но не
до конца понятных мне моментов.
1) В документации к модулю DB_File указывается, что
применение приведенного подхода с версиями до 1.72
этого модуля может приводить к нарушению целостности
базы данных. Предлагается вовсе отказаться от flock()
и воспользоваться модулями Tie::DB_Lock, Tie::DB_LockFile
или DB_File::Lock.
2) В документации к mod_perl в разделе "mod_perl and dbm files"
(
http://perl.apache.org/docs/1.0/guide/dbm.html) более
детально обсуждается эта проблема и прямо говорится:
"The suggested locking methods in the Camel book
and DB_File man page (before version 1.72, fixed in 1.73)
are flawed."
Там же наряду с Tie::DB_Lock, Tie::DB_LockFile,
DB_File::Lock и DB_File::Lock2 рассматриваются в том числе
и такие варианты решения проблемы блокировки:
Similar for the exclusive (EX), write access:
flock FLOCK_EX <===== start critical section
tie()
write...
sync()
untie()
flock FLOCK_UN <===== end critical section
3) Для модуля MLDBM, который я использую, также
разработан модуль MLDBM::Sync для решения вопроса
блокировки DBM файлов.
В связи со всем этим у меня остаются такие вопросы:
- будет ли корректно работать приведенный мной
"классический" (основанный на flock() ) подход к
блокировке DBM файлов с версиями модуля DB_File старше
1.72 (например, у меня установлена 1.801)?;
- будет ли этот подход корректно работать в моем случае,
то есть при использовании модуля MLDBM qw(DB_File)
(версия модуля 2.0)?;
- насколько жизнеспособен вариант блокировки, описанный
в 2), когда flock() стоит перед tie()?;
- действительно ли, если возможно, стоит совсем
отказаться от вариантов с flock() и использовать упомянутые
новые модули для решения проблем блокировки?
Отзовитесь, pls, кто сталкивался с этими вопросами.
Спасибо!