• ベストアンサー

ファイルロックの考え方について教えて下さい。

ファイルロックについてなのですが、調べる程に 混乱してきてしまい、投降させて頂きました。 どうかご指導よろしくお願い申し上げます。 hoge.txt(ログテキスト)があったとします。 Aさんがhoge.txtの内容一覧を開くときに 最初のロックがかかりますよね。 一覧を表示できた時点で一旦ロックが解除され、 次に、修正する内容を選び、修正内容の書き込みを している時点では、hoge.txtは、ロックがかかっていない 状態になっているのですよね? この状態の時に、Bさんがhoge.txtの内容一覧を開き 修正内容を選んだあと、Aさんがhoge.txtへ修正内容を 書き込んだとしたら、Bさんがhoge.txtへ修正内容を 書き込む時は、読み込んだ時点のhoge.txtとは内容が 変っているのだと思うのですが、これは問題ないのでしょうか? この場合、Aさんが、hoge.txtから一覧を参照し、修正内容を選び、 修正の書き込みを実行し終わるまでの時間ずっとhoge.txtはロック状態に あるのが望ましいのでしょうか? でも、参照・修正項目選択・修正書き込み・修正投降までの 時間となると、2、3分では済まない時もありますよね。 この時間ずっとロックというのはあまり良く無いのでは… とも考えております。 修正・閲覧までの数分間をロック状態にしなければ、確かに Aさんが修正しようとしているログを、修正書き込み作業している間に Bさんに、削除されてしまう可能性もある(?)と考えると 一連の作業終了までの間ロックしなくてはいけない、とも思うのですが そうなるとflockなどの機能ですと、一覧を表示して、修正こうもくを 選択した時点で、一旦hoge.txtは閉じられる事になり、ロック解除 状態になるのですよね…? それとも、一旦hoge.txtが閉じられた時は、ファイルサイズ0になるように しておけば、一連の作業中ずっとロック状態になっている、という 事になるのでしょうか…?

質問者が選んだベストアンサー

  • ベストアンサー
  • aton
  • ベストアンサー率47% (160/334)
回答No.5

> この状態の時に、Bさんがhoge.txtの内容一覧を開き > 修正内容を選んだあと、Aさんがhoge.txtへ修正内容を > 書き込んだとしたら、Bさんがhoge.txtへ修正内容を > 書き込む時は、読み込んだ時点のhoge.txtとは内容が > 変っているのだと思うのですが、これは問題ないのでしょうか? 問題あると思います。 Aさんが読み込み(状態0)→Bさんが読み込み(状態0)→Aさんが書き込み(状態0→状態1)→Bさんが書き込み(状態0→状態2) とすると,ファイルの最終状態は状態2ですから,Aさんによる修正は存在しなかったことになり,Bさんの修正だけが残ります。 Aさんにとっては「書き込みが成功したにも関わらず修正が反映されていない」ということになります。 > この場合、Aさんが、hoge.txtから一覧を参照し、修正内容を選び、 > 修正の書き込みを実行し終わるまでの時間ずっとhoge.txtはロック状態に > あるのが望ましいのでしょうか? 全ての人の修正を確実に反映させることが必要なら,答は「yes」です。 > でも、参照・修正項目選択・修正書き込み・修正投降までの > 時間となると、2、3分では済まない時もありますよね。 > この時間ずっとロックというのはあまり良く無いのでは… > とも考えております。 安全性をとるか,利便性をとるかという判断かと思います。 基本的には,できるだけロックを遅らせる(例えば実際に修正すると決めた時点再度ファイルを読み直し,その時点でロックをかける)のだと思います。 別な考え方としては,CVSのように,一つのファイルに二人の人が同時に修正を行ったら,それを同一ファイルの二つの異なる分岐バージョンとして扱うという方法もあります。 これだと長時間のロックは不要になりますが,バージョン分岐を管理する必要が出てきます。 > そうなるとflockなどの機能ですと、一覧を表示して、修正こうもくを > 選択した時点で、一旦hoge.txtは閉じられる事になり、ロック解除 > 状態になるのですよね…? flockではカバーできない,例えば複数CGIにまたがるようなファイルロックを行いたい場合,最も一般的な手法は「ロックファイル」を作ることだと思います。 基本的には, ・ファイルを開く前にロックファイルがあるかどうか確認する ・ロックファイルがあればあきらめる ・なければロックファイルを作成してファイルを開く ・ファイルを閉じるときは,ファイルを閉じてからロックファイルを削除する という感じになります。

sibazuke
質問者

お礼

aton様。 ご指導ありがとう御座いました。 やはり、flockだけでの実装は難しいですね…。 一番無難で簡単です、と紹介されていたので 安易に使おうとした事が迷路の元でした。 ロックファイルを作成する案を使わせて頂く事に致しました。 ロックを掛けたい時に作成するのではなく、最初から 作って置いて、0ならOK1ならロック中です、という旨のメッセージを書く、という方法で行こうと思います。 ご指導、ありがとう御座いました。

その他の回答 (7)

回答No.8

#7さんの詳細と同じようなものですが、開放していますので、 実際にHTMLソースを見ていただければと思います。 #URL露出になってしまいますが・・汗 http://pyukiwiki.daiba.cx/pyukiwiki/PyukiWiki017/ 一部取り出すと・・・ <form action="nph-index.cgi" method="post" id="editform" name="editform"> <input type="hidden" name="myConflictChecker" value="Sun Jul 2 17:33:20 2006"> <input type="hidden" name="mypage" value="あいうえお"> <input type="hidden" name="refer" value=""> <input type="hidden" name="refercmd" value="edit"> <input type="hidden" name="cmd" value="edit"> のような感じになっており、Submitボタンを押した時、時刻とまた比較します。 #実際には、これはファイルのタイムスタンプではなく、別のステータス用のデータベースを持っており、実際にはそちらと比較しています。 ためしに、このページで以下のことをやってみてください。 ・新規ページをつくり、普通に保存する。 ・そのページを右クリック→新しいウィンドウで別窓で編集画面を開く ・更に、そのページを右クリック→新しいウィンドウで別窓で編集画面を開く ・後に開いた画面を少し変更して保存 ・前のページで少し変更して保存 <衝突というメッセージが出ます。

参考URL:
http://pyukiwiki.daiba.cx/pyukiwiki/PyukiWiki017/
回答No.7

そのようなCGIを作った事があります あるサイトのtoppageの一部にhoge.txt等のfileをSSIでincludeしますが 登録されたメンバーが hoge.txtを編集して災害のニュース速報を流すと言うものです。 で、fileロックと自分が編集中に他の人に更新された場合に処理中止を行うことは別物です。 前者はflockやmkdirなどで行い、後者は#2さんの書かれたようにタイムスタンプをつけていました。 細かく書くと 1.hoge.txt読み込み+タイムスタンプ取得 2.編集form表示 (1.のタイムスタンプ情報もhiddenタグで送るようにする)  ここで通常数分間 編集作業を行うがサーバーとのセッションが無いので問題なし 3.form送信ボタンを押す 4.mkdirなどでロック (1. 2.の時点ではロック無しと言うことです) 5.再度hoge.txt読み込み+タイムスタンプ取得して  formで送られた1.で取得されたタイムスタンプと比較して、一致すればhoge.txtへの書き込み  不一致なら「あなたが編集中に他の人に行進されました」と表示してfile書き込みせずエラー処理+ロック解除 6.編集しなおしたければ1.からやり直し出来るようにリンクを表示

sibazuke
質問者

お礼

umasikajiro様。 ご指導ありがとうございました。 細部の詳細まで教えて頂き、とても参考になりました。 一つ、タイムスタンプ取得時の事で疑問に思ったのですが、 最初のhoge.txtを開いた時点で取得したタイムスタンプは、 タイムスタンプ専用のテキストなどを容易して書き込んで置き、 編集作業後、「form」ボタンを押されたときに、hiddenで渡ってきた タイムスタンプとそのタイムスタンプ記述用のテキストの内容と 一致するか否かを判定させる、という方法で良いのでしょうか…?

回答No.6

#2です。 それでは、リネームロックはいかがでしょうか? うちによる実装は、これです。 http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/pyukiwiki/PyukiWiki-Devel/lib/Nana/Lock.pm?rev=1.46&view=markup それ以外にも・・ http://www.din.or.jp/~ohzaki/perl.htm#File_Lock http://homepage1.nifty.com/glass/tom_neko/web/web_04.html http://www.hyuki.com/yukiwiki/wiki.cgi?YukiWikiLock 等があります。

sibazuke
質問者

お礼

ymda様。 何度もご指導ありがとうございます。 リネームによるロックの紹介していただいたサイトさんなど とても勉強になりました。 しかし、長いコードになりますよね。 逆を返せば、それだけロックは重要だと言う事ですよね。 今回flockはなんとなく不都合が出るような気がしましたので、ロックファイルを用意し、0なら書き込みOKで 1ならロック中です、という旨のメッセージが出るような 仕組みで行こうかと考え中です。 ○分以上ロックがかかったままだと自動的にロック解除にする仕組みでうがーとなっておりますが…(泣) 頑張ります。ご指導ありがとう御座いました。

  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.4

やるかやらないかは別として違う考え方。 ・データに修正フラグ、削除フラグを用意しておく。 ・修正しようとするときは修正フラグに時刻を書き込み。 ・そのまま修正せずに終了するとデッドロックになるので、数分で修正フラグを解除する。 (修正フラグを解除された場合に修正しようとした場合(タイムアウトになった場合)は再度最初からやり直し ・削除したものには削除フラグを立てる。 と言うようなことをすれば一応整合性も保たれると思います。 抜けているところもあるとは思いますが。 ファイル全体をロックするのではなく、データ単位でロックするという考え方ですね。 どのようなやり方がいいかは自分の環境に合わせて考える必要がありますね。

sibazuke
質問者

お礼

moon_night様。 いつもご指導ありがとうございます。 そのような方法もあったのですね! ファイルロック、という言葉だけで検索をし 考えあぐねておりましたので、目からうろこでした。 今回は、ロックファイルを作成する方向で行こうと思います。 フラグを立てるという方法は、色々使えそうなので 覚えようと思います。 ご指導、ありがとうございました。

  • kalze
  • ベストアンサー率47% (522/1092)
回答No.3

スペル間違えました。 margeではなく、mergeです。 簡単にいうと、2つのファイルがあったとして、その二つの違いを取得する。 その2つをうち、違う部分が競合してなければ結合するような感じ。 ルールはいろいろありますが。 flockなどのファイルロックは、ファイルへの操作中に他のプロセスからファイルへの操作を行われるのを防ぐためにあるものです。 そのため、ファイルへの操作中以外の保護については、なんらかの方法を検討・実装しなければなりません。 #2様の説明の補足として。 ファイルロックは同時書き込みだけではなく、ファイル操作全般の制御になります。 あるプロセスが書き込みを行っている最中に他のプロセスで読み込まれると問題がある場合があるように(逆もまたしかりですが) そのため、一般的なファイルロック関数は、なにを禁止するかを指定します。 読み込みしているので読み込みは問題ないですよとか、書き込みしているので読み書きしないでねとか。

sibazuke
質問者

お礼

kalze様。 何度もすみません…。 ご指導ありがとうございまいした。 今回は、ロックファイルを容易して、0ならOK1ならロック中ですという旨のメッセージを出す方向で行こうと 思います。 ご指導、ありがとう御座いました。

回答No.2

通常、複数人がいじれるようなサーバー等ではこのような処理をします。 ・hoge.txt を読み込みで開くと同時に、最低でもタイムスタンプを保持する。 ・hoge.txt を書き込む前に、タイムスタンプが同一であるかチェックし、以前の内容と同じであるかチェックする。 これにより、他人が先に編集して書き込みした場合、その後に書き込みしようとする人にわかる仕組みになります。 また、一般のアプリであれば、常時インターバルで(10秒ごとでも)タイムスタンプをチェックすることで、他人が編集したという通知がほぼリアルタイムでできるかと思います。 これらは、適時、アプリ側で制御する必要があります。 ---- ちなみに、OS等に搭載しているファイルロックは、このようなものに対応しているものではありません。 あくまで「同時書込」を阻止するためのロックです。 #OSでなくても、いろんな方法でロックを実装できるんですけどね・・・

sibazuke
質問者

お礼

ymda様。 いつもご指導ありがとうございます。 シンボリックリンクやmkdirなどでhoge.txtの名前自体を変更 したりディレクトリを作成する方法が、ご指導頂いた タイムスタンプ作成にあたると解釈しても良いでしょうか…? 使用したいサーバーで、flockが使用可能な事がわかったので 使ってみたいな、と思い色々検索をした事から今回の疑問に 繋がったのです。 OSはWindowsで、symlinkは使用できないとありました。 ただ、mkdirや(使えたとしても)symlinkは何かのはずみで ロック解除できないままになった時に、手作業で該当のファイルや ディレクトリを削除しなくてはいけない、という注意書きを 見つけ、それは嫌だなぁと感じた事から、安易にflockを 使用しようと決めたものの、ファイルを閉じる=ロック解除に なるという記述も見つけて、今回の疑問がグルグルとなってしまいました。 ファイルロックって奥が深いですね…。

  • kalze
  • ベストアンサー率47% (522/1092)
回答No.1

>書き込む時は、読み込んだ時点のhoge.txtとは内容が >変っているのだと思うのですが、これは問題ないのでしょうか? この懸念は正しいです。 これをどうやって解消するかは、どういうシステムでどれくらいその問題が起こるのかということを検討しての設計の問題となります。 あまり変更頻度が高くないとかで、致命的で無ければ問題なしとすることもあります。 ロックかけっぱなし(もちろんロックは自分で実装する)で解決させることもあります。 一覧を開いたときと、修正を反映させる処理のときとでファイルの内容が変わっていたら修正を反映させずに警告をだすという方法もあります。 また、margeして、修正箇所に衝突がなければ反映させ、衝突があれば警告するという方法もあります。 結局は、どうなってほしいかと、コストとを比較して、どう対策するか次第となります

sibazuke
質問者

お礼

kalze様。 ご指導ありがとう御座いました。 閲覧する人は50人程度で、ファイル操作(書き込み・修正・削除など)をする人は10人足らずなので、 まったくの同時期に、最初書き込みさせて頂いたような ニアミスに近い修正が入る事はまず稀だとは思うのですが それでも、もし万が一!と考え出すとグルグルしてしまいました。 問題なしの方で設計してよいのか、一度相談しなおして みようと思います。 それから、margeとはどういう意味なのでしょうか? 関数リファレンスでは該当のモノが見つからず、英和辞書で しらべてみたのですが「マーガリン」(笑)で…。 よければmargeの意味を教えて頂けないでしょうか。

関連するQ&A