トランザクション NTFS のプログラミングに関する考慮事項
トランザクション NTFS のさまざまなプログラミングに関する考慮事項の説明については、次のセクションを参照してください。
- トランザクションされるファイルの変更
- 圧縮
- ファイルまたはディレクトリの作成
- ファイルの削除
- ディレクトリの削除
- ディレクトリのロックに関する問題
- ディレクトリ列挙
- メモリ マップト ファイル
- 名前付きストリーム
- ファイルまたはディレクトリの名前を変更する
- 再解析ポイント
- エラー コード
- 暗号化されたファイル システム
- ファイル I/O 関数とトランザクション NTFS
トランザクションされるファイルの変更
ファイルの内容、ストリーム、再解析ポイント、属性、ファイル システム名前空間の変更など、ほとんどのファイル変更は処理されます。 これらの変更のいずれかがトランザクション ファイル ハンドルに対して行われると、変更は他のトランザクションから分離され、トランザクションがロールバックされると変更は元に戻されます。
ファイルの内容、メタデータ、またはファイル システムの名前空間に影響しない変更 (圧縮や最適化の変更など) は処理されません。 これらの変更は他のトランザクションから分離されず、トランザクションがロールバックされても元に戻されません。
圧縮
トランザクションで開かれたファイルの圧縮状態は変更できません。
ファイルまたはディレクトリの作成
トランザクションで作成されたファイルまたはディレクトリは、現在のトランザクションの外部には表示されません。 このトランザクションの外部では、同じ名前のファイルを作成しようとすると、エラー ERROR_TRANSACTIONAL_CONFLICTで失敗し、トランザクションがコミットまたはロールバックされたときのファイル名を実質的に予約します。
ファイルの削除
DeleteFileTransacted 関数を呼び出して削除されたファイルまたはディレクトリは、外部のすべてのリーダーに対して引き続き表示されます。
注意
ファイルに対するすべてのトランザクション ハンドルは、トランザクションの終了前に閉じる必要があります。 ハンドルが正しく閉じていない場合、削除は行われません。 削除操作をトランザクションの一部と見なすには、コミットを実行する前に、ファイルに対するすべての開いているハンドルを閉じる必要があります。 これは、Windows ファイル I/O サブシステムの一部として、操作がトランザクションされていない場合でも、最後のハンドルが閉じられるまで、システムが実際にファイルを削除しないためです。
ディレクトリの削除
RemoveDirectoryTransacted 関数を呼び出して削除されたディレクトリは、すべての外部リーダーに表示されます。
注意
トランザクションディレクトリ操作のオープン ハンドルには、ファイルと同じ制約があります。 詳細については、「 ファイルの削除」を参照してください。
ディレクトリのロックに関する問題
トランザクションでファイルが変更された場合、ファイルへのパスのすべてのディレクトリ コンポーネントは、トランザクションが終了するまで 、名前の変更に対して固定 と呼ばれます。 つまり、トランザクションがコミットまたはロールバックされるまで、システムは名前を変更できなくなります。 進行中のトランザクションで変更されたファイルに先祖であるディレクトリの名前を変更しようとすると、エラー ERROR_CANT_BREAK_TRANSACTIONAL_DEPENDENCYで失敗します。
ディレクトリ列挙
ディレクトリの内容は、列挙する API ( FindFirstFileTransacted 関数や FindNextFile 関数など) を使用した結果、列挙の進行中に変更できます。
トランザクション外のディレクトリに対する変更は、トランザクションから分離されず、トランザクション内ですぐに表示されます。 たとえば、非トランザクション ライターがディレクトリにファイルを追加した場合、 FindFirstFileTransacted 関数または FindNextFile 関数を呼び出すと新しいファイルが返されるように、新しいファイルがトランザクション内ですぐに表示されます。
トランザクション内のディレクトリに加えられた変更は、トランザクションがコミットされるまで分離されます。 たとえば、トランザクションの一部としてディレクトリに作成されたファイルです。 FindFirstFile 関数または FindNextFile 関数を呼び出す非トランザクション リーダーでは、トランザクションがコミットされるまで、新しく作成されたファイルは表示されません。
メモリ マップト ファイル
クライアントは FlushViewOfFile 関数を呼び出し、ファイル マッピング オブジェクトを閉じ、関連するトランザクションをメモリ マップファイルにコミットする前にファイル ハンドルを閉じる必要があります。
名前付きストリーム
名前付きストリームは完全にトランザクションですが、ロックはストリーム レベルではなくファイル レベルで行われます。 ロックされたファイル内のストリームを変更しようとするトランザクションの外部からのライターは、エラー ERROR_SHARING_VIOLATIONを受け取ります。
トランザクション内のセカンダリ ストリームの名前を変更することはできません。
ファイルまたはディレクトリの名前を変更する
ファイルの名前をトランザクション操作として変更するには、 MoveFileTransacted を呼び出してファイルを移動します。
再解析ポイント
再解析ポイントに対する変更はトランザクション処理されます。つまり、トランザクション内のファイルに新しい再解析ポイントが割り当てられると、他のトランザクションには表示されません。 同様に、既存の再解析ポイントの変更または削除は、コミットまで表示されません。
エラー コード
カーネル トランザクション マネージャー (KTM) は、6700 ~ 6799 の範囲のシステム エラー コードを使用します。 トランザクション NTFS (TxF) では、6800 ~ 6899 の範囲の Windows エラー コードが使用されます。 詳細については、「WinError.h」および「システム エラー コード (6000-8199)」を参照してください。
暗号化されたファイル システム
TxF では、EFS ファイルに対する操作はサポートされていません。 EFS で暗号化されたファイルをトランザクション用に開くことはできません。 EFS ファイルで CreateFileTransacted 関数を呼び出すと、エラー ERROR_EFS_NOT_ALLOWED_IN_TRANSACTIONで失敗します。 同様に、トランザクション内のファイルに対して EncryptFile 関数を呼び出すと、エラー ERROR_EFS_NOT_ALLOWED_IN_TRANSACTIONで失敗します。
ファイル I/O 関数とトランザクション NTFS
TxF には、ファイル名を受け取り、ファイル ハンドルを受け取る既存のファイル I/O API 関数の動作を変更する新しいトランザクション関数が用意されています。
Transacted Functions
非トランザクション バージョンの代わりに次のトランザクション関数のいずれかを呼び出さない場合、操作はトランザクションされません。
- CopyFileTransacted
- CreateDirectoryTransacted
- CreateFileTransacted
- CreateHardLinkTransacted
- CreateSymbolicLinkTransacted
- DeleteFileTransacted
- FindFirstFileNameTransactedW
- FindFirstFileTransacted
- FindFirstStreamTransactedW
- GetCompressedFileSizeTransacted
- GetFileAttributesTransacted
- GetFullPathNameTransacted
- GetLongPathNameTransacted
- MoveFileTransacted
- RemoveDirectoryTransacted
- SetFileAttributesTransacted
たとえば、 CreateFile 関数のトランザクション バージョンは CreateFileTransacted になりました。
TxF によって変更されたファイル I/O 関数
次の表は、トランザクション NTFS の影響を受ける動作を持つ関数の一覧です。 たとえば、ReadFile 関数の動作は、hFile パラメーターが CreateFile 関数または CreateFileTransacted 関数によって作成されたかどうかによって異なります。
機能 | 説明 |
---|---|
CloseHandle |
アプリケーションは、トランザクションがコミットされる前に、トランザクションにバインドされているすべてのハンドルを閉じる必要があります。 削除操作を実行するには、トランザクションをコミットする前に、 アプリケーションで FILE_FLAG_DELETE_ON_CLOSE で開かれたトランザクション ハンドルを閉じる必要があります。 |
CreateFileMapping |
hFile に関連付けられたトランザクションがある場合、この関数によって作成されるファイル マッピング オブジェクトは、同じトランザクションに関連付けられます。 このファイル マッピング オブジェクトのビューを通じて行われた変更は、トランザクションされます。 アプリケーションは、トランザクションされた変更をコミットする前に、 FlushViewOfFile を呼び出し、すべてのビューのマップを解除し、すべてのハンドルをファイル マッピング オブジェクトに閉じる必要があります。 |
FindNextFile |
ファイル列挙ハンドルにバインドされたトランザクションがある場合、返されるファイルはトランザクション分離規則の対象になります。 |
FSCTL_SET_COMPRESSION |
CreateFileTransacted によって開かれたファイルの圧縮状態を変更することはできません。 |
GetFileInformationByHandle と GetFileInformationByHandleEx |
ファイル ハンドルにバインドされたトランザクションがある場合、この関数は分離ファイル ビューの情報を返します。 |
GetFileSize と GetFileSizeEx |
ファイル ハンドルにバインドされたトランザクションがある場合、この関数は分離ファイル ビューの情報を返します。 |
GetVolumeInformation |
ボリュームがファイル システム トランザクションをサポートしている場合、この関数は lpFileSystemFlags でFILE_SUPPORTS_TRANSACTIONSを返します。 |
MapViewOfFile と MapViewOfFileEx |
マップされているファイル マッピング オブジェクトの作成に使用されるファイル ハンドルに関連付けられているトランザクションがある場合は、関連付けられたビューがトランザクションされます。 ビューを使用してファイルに対するトランザクション変更を行う場合、ユーザーは FlushViewOfFile を呼び出し、ファイル マッピング オブジェクトを閉じ、関連付けられたトランザクションをコミットする前にファイル ハンドルを閉じる必要があります。 |
ReadDirectoryChangesW |
ディレクトリ ハンドルにバインドされたトランザクションがある場合、通知にはディレクトリの分離ビューが反映されます。 ディレクトリのトランザクション ビュー外のファイルに対する変更は、通知には含まれません。 |
ReadFile、 ReadFileEx、 および ReadFileScatter |
ファイル ハンドルにバインドされたトランザクションがある場合、関数はファイルのトランザクション ビューからデータを返します。 トランザクション読み取りハンドルは、ハンドルの期間中、ファイルの同じビューを表示することが保証されます。 |
SetEndOfFile |
ハンドルにバインドされたトランザクションがある場合は、ファイルの終わり位置の変更がトランザクションされます。 |
SetFileInformationByHandle |
ハンドルにバインドされたトランザクションがある場合、加えられた変更は、情報クラス FileBasicInfo、FileRenameInfo、FileAllocationInfo、FileEndOfFileInfo、および FileDispositionInfo に対して処理されます。 |
SetFileShortName |
ハンドルにバインドされたトランザクションがある場合は、ファイルの短い名前の変更が処理されます。 |
SetFileTime |
ハンドルにバインドされたトランザクションがある場合は、ファイル時刻の変更が処理されます。 |
WriteFile、 WriteFileEx、 および WriteFileGather |
ファイル ハンドルにバインドされたトランザクションがある場合は、ファイル書き込みが処理されます。 |