特定のUSBキーが接続されたときに実行されるWindowsサービスを作成しています。それは簡単です。FTPサーバーに接続し、いくつかのファイルをダウンロードして、USB上の(暗号化された)アーカイブに保存します。アーカイブは、クライアントに提供されているツールを使用して読み取り専用で開くことができます(ただし、これは私の問題とは関係ありません)。
このサービスは、USBをマスターサーバーと同期させるために使用されます(Dropboxとほとんど同じですが、ダウンロードと同期されたフォルダーのみがリムーバブルメディア上にあります)。アーカイブは数ギガバイトまで大きくなる可能性があります。約400人のユーザーのキーで毎週約1GBのファイルが更新されます。
更新プロセス全体がユーザーに対して透過的であるため、データがアーカイブに書き込まれているときにUSBが抜かれる可能性は無視できません(私がなんらかの悲鳴を上げて派手な警告を出したとしても:抜かないでください)。アーカイブを破損すると、アーカイブ全体を再度ダウンロードする必要があります。つまり、すでにロードされているサーバーでかなりの帯域幅が浪費されています。
したがって、基本的には、アーカイブへの書き込みを処理する必要があります。コンテナを不整合な状態にしない限り、失敗しても問題ありません。ファイルが完全に書き込まれているか、そうでないかのどちらかです。コンテナが実際にファイルを「認識」していなくても、ファイルが部分的に書き込まれていても問題ありません。
質問はここにあります: データの一貫性を常に保証するにはどうすればよいですか?具体的には、IO操作をトランザクションとして機能させるにはどうすればよいですか?あなたは何を提案しますか?自分で何かを実装しませんか?または、この機能を提供するコンテナはすでにありますか?
これは私がこれまでに得たものです:
- 新しいアーカイブを作成し、コミット時に名前を変更します。不可能です。アーカイブが大きすぎます。
- Zip / Tar / 7z:不適切、書き込みに失敗するとアーカイブが破損します
- Truecrypt:ファイルシステムドライバーが必要なため、不適切です(ユーザーがドットで持っていない管理者権限)。
- ファイルシステムをファイルにマッピングする必要があるもの:不適切です。管理者でないとそれができないことは確かですが、可能であれば、それは素晴らしいことです。
- SQLite DBへのファイルの保存:それはACIDなので、実際に解決策になる可能性があります。ただし、SQLiteのBLOB容量には制限があるため、ファイルを分割する必要があります。あまりエレガントではありませんが、私はそのように行く準備ができています。また、SQLiteのトランザクションジャーナルは、大きなBLOBを格納するときにかなり大きくなる可能性があります。
- 自分で実装する:できるだけ避けたいのですが、恐れることはありません。トピックがかなり複雑だと思います。
この質問が一般的すぎる場合は、SUなどに移動してください。