7. Write Lock (書き込みロック)
本セクションでは、本仕様で定義されている唯一のロックタイプである書き込みロック (Write Lock) について説明します。書き込みロックは、ロック所有者にリソースを変更する権利を付与するロックです。ロック所有者は、ロックを作成したプリンシパルです。
7.1 Write Locks and Properties (書き込みロックとプロパティ)
書き込みロックを持たないユーザーはリソースのコンテンツを変更できませんが、リソースのデッドプロパティを変更してもよい (MAY) です。これにより、例えば、プリンシパルが書き込みアクセス権を必要とせずに、ロックされたリソースにコメントを追加できます。
ライブプロパティは通常、サーバーによって強制されるセマンティクスを持っています。したがって、サーバーは、リソースがロックされているときにライブプロパティへの変更を許可するかどうか、およびどのように許可するかについて裁量権を持っています。例えば、サーバーは、リソースがロックされている場合でもライブプロパティの変更を許可してもよい (MAY) です。
7.2 Avoiding Lost Updates (更新の損失を回避する)
書き込みロックの目的は、更新の損失 (Lost Updates) を防ぐことです。更新の損失は、複数のプリンシパルが調整なしにリソースを変更しようとし、その結果、1つ以上のプリンシパルの変更が後続の更新によって上書きされるときに発生します。
書き込みロックはシリアライゼーションメカニズムを提供します:ロックホルダーのみがロックされたリソースを変更できます。これにより、変更が同時ではなく順次発生することが保証され、更新の損失問題を防ぎます。
更新損失シナリオの例(ロックなし):
- ユーザーAがリソースのバージョン1を取得
- ユーザーBがリソースのバージョン1を取得
- ユーザーAが変更して保存 → バージョン2を作成
- ユーザーBが(バージョン1に基づいて)変更して保存 → バージョン3を作成し、Aの変更を上書き
書き込みロックを使用:
- ユーザーAがリソースをロック
- ユーザーBが変更を試みる → 423 Lockedエラーを受信
- ユーザーAが変更してロック解除
- ユーザーBがロックして変更可能
7.3 Write Locks and Unmapped URLs (書き込みロックと未マップURL)
未マップURLへの成功したLOCKリクエストは、ロックされた空のリソースを作成します。このメカニズムにより、クライアントはリソースコンテンツを作成する前にURLを予約できます。
ロックされた空のリソースが作成されるとき:
- リソースにはコンテンツがありません(長さゼロのエンティティ)
- リソースは指定されたロックでロックされます
- 後続のPUTまたはMKCOLでリソースにコンテンツを追加できます
- ロックトークンをPUTまたはMKCOLリクエストと共に送信する必要があります
この「ロックヌルリソース (Lock-null Resource)」メカニズムは、付録Dで詳しく説明されています。
7.4 Write Locks and Collections (書き込みロックとコレクション)
コレクションへの書き込みロックは、コレクションリソース自体をロックし、コレクションのメンバーシップへの変更(内部メンバーの追加または削除)を防ぎます。
深度無限のロックがコレクションに適用される場合:
- コレクション自体がロックされます
- すべての内部メンバーがロックされます
- すべての子孫リソースが再帰的にロックされます
- コレクションに追加された新しいメンバーは自動的にロックされます
ロックの継承:新しいリソースがロックされたコレクション(深度無限)に追加されると、新しいリソースは親コレクションからロックを継承します。
7.5 Write Locks and the If Request Header (書き込みロックとIfリクエストヘッダー)
クライアントは If リクエストヘッダーを使用してロックトークンを送信します。このヘッダーは、ロックトークンの存在に基づいてメソッドの条件付き実行を可能にします。
If ヘッダー構文は以下をサポートします:
- 単一のロックトークン
- 複数のロックトークン(複数のロック用)
- タグ付きリスト(特定のURLとトークンを関連付ける)
- NOT条件(ロックの不在を要求)
7.5.1 Example - Write Lock and COPY (例 - 書き込みロックとCOPY)
COPY /source HTTP/1.1
Host: example.com
Destination: http://example.com/destination
If: `http://example.com/destination` (<opaquelocktoken:token123>)
このリクエストは、クライアントが /destination のロックトークンを保持している場合にのみ、/source を /destination にコピーします。
7.5.2 Example - Deleting a Member of a Locked Collection (例 - ロックされたコレクションのメンバーの削除)
DELETE /folder/file.txt HTTP/1.1
Host: example.com
If: `http://example.com/folder/` (<opaquelocktoken:folder-token>)
ロックされたコレクションのメンバーを削除するには、クライアントはコレクションのロックトークンを送信する必要があります。
7.6 Write Locks and COPY/MOVE (書き込みロックとCOPY/MOVE)
COPYメソッドは、宛先に新しいリソースを作成します。ソースがロックされていても、新しいリソースは自動的にロックされません。ロックはコピーされません。
MOVEメソッドは、意味的にはCOPYに続いてDELETEと同等です。リソースが移動されると、ソースのロックは削除されます。宛先は自動的にロックされません。
COPYまたはMOVEの宛先がロックされている場合、クライアントは宛先を上書きするために適切なロックトークンを送信する必要があります。
7.7 Refreshing Write Locks (書き込みロックのリフレッシュ)
ロックには有限のライフタイムがあります。ロックの早期期限切れを防ぐために、クライアントは次の方法でロックをリフレッシュできます:
Ifヘッダーに同じロックトークンを含める- リクエストボディなし(または空の
lockinfo要素)
サーバーは新しいタイムアウト値で応答します。ロックのリフレッシュにより、ロックが期限切れにならない長期編集セッションが可能になります。
ロックリフレッシュの例:
LOCK /resource HTTP/1.1
Host: example.com
If: (<opaquelocktoken:token123>)
Timeout: Second-3600
サーバーはロックのタイムアウトを延長し、新しい有効期限を返します。