Skip to main content

7. 写锁 (Write Lock)

本节描述写锁,这是本规范中定义的唯一锁类型。写锁是授予锁所有者修改资源权利的锁。锁所有者是创建锁的主体。

7.1 写锁和属性 (Write Locks and Properties)

虽然没有写锁的人不能更改资源的内容,但他们可以修改资源的死属性。例如,这允许主体在不需要写访问权限的情况下向锁定的资源添加注释。

活属性通常具有由服务器强制执行的语义。因此,服务器可以自行决定是否以及如何允许在资源被锁定时更改活属性。例如,即使资源被锁定,服务器也可以允许修改活属性。

7.2 避免丢失更新 (Avoiding Lost Updates)

写锁的目的是防止丢失更新。当多个主体在没有协调的情况下尝试修改资源时,会发生丢失更新,导致一个或多个主体的更改被后续更新覆盖。

写锁提供了序列化机制:只有锁持有者可以修改锁定的资源。这通过确保修改按顺序而不是并发发生来防止丢失更新问题。

丢失更新场景示例 (Example Lost Update Scenario) (无锁定):

  1. 用户A检索资源版本1
  2. 用户B检索资源版本1
  3. 用户A修改并保存 → 创建版本2
  4. 用户B修改(基于版本1)并保存 → 创建版本3,覆盖A的更改

使用写锁 (With Write Lock):

  1. 用户A锁定资源
  2. 用户B尝试修改 → 收到423 Locked错误
  3. 用户A修改并解锁
  4. 用户B现在可以锁定和修改

7.3 写锁和未映射的URL (Write Locks and Unmapped URLs)

对未映射URL的成功LOCK请求会创建一个被锁定的空资源。此机制允许客户端在创建资源内容之前保留URL。

创建锁定的空资源时:

  • 资源没有内容(零长度实体)
  • 资源使用指定的锁锁定
  • 后续的PUT或MKCOL可以向资源添加内容
  • 必须在PUT或MKCOL请求中提交锁令牌

此"锁空资源 (lock-null resource)"机制在附录D中详细描述。

7.4 写锁和集合 (Write Locks and Collections)

集合上的写锁锁定集合资源本身,防止修改集合的成员资格(添加或删除内部成员)。

当深度无限锁应用于集合时:

  • 集合本身被锁定
  • 所有内部成员被锁定
  • 所有后代资源递归锁定
  • 添加到集合的新成员自动锁定

锁继承 (Lock Inheritance): 当新资源添加到锁定的集合(深度无限)时,新资源从父集合继承锁。

示例 (Example):

集合 /folder/ 使用 Depth: infinity 锁定
- 无法向 /folder/ 添加新成员
- 无法修改 /folder/file1.txt
- 无法删除 /folder/subfolder/
- 无法修改 /folder/subfolder/file2.txt

7.5 写锁和If请求头 (Write Locks and the If Request Header)

客户端使用If请求头提交锁令牌。此头允许基于锁令牌存在的方法条件执行。

If头语法支持:

  • 单个锁令牌
  • 多个锁令牌(用于多个锁)
  • 标记列表(将令牌与特定URL关联)
  • NOT条件(要求不存在锁)

7.5.1 示例 - 写锁和COPY (Example - Write Lock and COPY)

COPY /source HTTP/1.1
Host: example.com
Destination: http://example.com/destination
If: \`http://example.com/destination\` (<opaquelocktoken:token123>)

此请求将/source复制到/destination,但仅当客户端持有/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 写锁和COPY/MOVE (Write Locks and COPY/MOVE)

COPY方法在目标位置创建新资源。新资源不会自动锁定,即使源被锁定。锁不会被复制。

MOVE方法在语义上等同于COPY后跟DELETE。移动资源时,源上的锁被删除。目标不会自动锁定。

如果COPY或MOVE的目标被锁定,客户端必须提交适当的锁令牌来覆盖目标。

7.7 刷新写锁 (Refreshing Write Locks)

锁具有有限的生命周期。为了防止过早的锁过期,客户端可以通过提交带有以下内容的LOCK请求来刷新锁:

  • If头中的相同锁令牌
  • 无请求主体(或空的lockinfo元素)

服务器响应新的超时值。锁刷新允许长期编辑会话而不会锁过期。

锁刷新示例 (Example Lock Refresh):

LOCK /resource HTTP/1.1
Host: example.com
If: (<opaquelocktoken:token123>)
Timeout: Second-3600

服务器延长锁超时并返回新的过期时间。