フォローアップ:多くのリーダーと1人のライターがいるファイルを安全に更新するにはどうすればよいですか?
以前の質問で、FileChannelのロックを使用して、読み取りと書き込みの順序を確認できることがわかりました。
しかし、ライターが書き込みの途中で失敗した場合(たとえば、JVMがクラッシュした場合)、どのように対処しますか?この基本的なアルゴリズムは次のようになります。
WRITER:
lock file
write file
release file
READER:
lock file
read file
release file
中にJVMがクラッシュした場合はwrite file
、ロックが解除されることを確認してください。ただし、ファイルが不完全になっています。完全なものを常に読みやすくしたい。古いコンテンツと新しいコンテンツのどちらかであり、その間には何もありません。
私の最初の戦略は、一時ファイルに書き込んでから、内容を「ライブ」ファイルにコピーすることでした(適切なロックを確保しながら)。このためのアルゴリズムは、
WRITER:
lock temp file
write temp file
lock file
copy temp to file
release file
release temp
delete temp
READER:
lock file
read file
release file
良い点の1つは、delete temp
別のライターによって既にロックされている場合、一時を削除しないことです。
ただし、の間にJVMがクラッシュした場合、そのアルゴリズムは処理しませんcopy temp to file
。それで私はcopying
旗を追加しました、
WRITER:
lock temp file
write temp file
lock file
create copying flag
copy temp to file
delete copying flag
release file
release temp
delete temp
READER:
lock file
if copying flag exists
copy temp to file
delete copying flag
delete temp
end
read file
release file
copying
ファイルはファイルロックによって保護されているため、ファイルにアクセスすることは2つありません。
さて、これはそれを行う方法ですか?非常に単純なものを確保することは非常に複雑に思えます。これを処理するJavaライブラリはありますか?
編集
さて、私は3回目の試みで間違いを犯すことができました。リーダーは、温度を上げるときにロックを保持しませんcopy temp to file
。また、一時ファイルをロックするだけの簡単な修正ではありません。これにより、ライターとリーダーが異なる順序でロックを取得し、デッドロックが発生する可能性があります。これは常に複雑になっています。これが私の4回目の試みです。
WRITER:
lock file
write temp file
create copying flag
copy temp to file
delete copying flag
delete temp
release file
READER:
lock file
if copying flag exists
copy temp to file
delete copying flag
delete temp
end
read file
release file
今回は一時ファイルがメインロックで保護されているため、独自のロックも必要ありません。
編集2
私がJVMクラッシュと言うとき、私は実際に電源が切れて、UPSを持っていなかったと言うことを意味します。
編集3
私はまだ別の間違いをすることができました。書き込みまたは読み取りを行っているファイルをロックしないでください。入出力ストリームを実装していないJavaでRandomAccessFileを使用しない限り、読み取りロックと書き込みロックの両方を取得できないため、これにより問題が発生します。
代わりに実行したいのは、読み取りまたは書き込み中のファイルを保護するロックファイルをロックすることです。更新されたアルゴリズムは次のとおりです。
WRITER:
lock
write temp file
create copying flag
copy temp to file
delete copying flag
delete temp
release
READER:
lock
if copying flag exists
copy temp to file
delete copying flag
delete temp
end
read file
release
ロックと解放は、ファイル、一時ファイル、およびコピーフラグを保護します。唯一の問題は、リーダーロックを共有できないことですが、実際には共有できません。読者は常にファイルを変更する機会があったので、そもそも共有可能なロックを作成するのは間違っていたでしょう。