RESTful事务与隔离定理支持的并发控制
立即解锁
发布时间: 2025-08-20 00:14:02 阅读量: 2 订阅数: 6 


Web Engineering与新闻文章内容提取方法综述
# RESTful事务与隔离定理支持的并发控制
## 1. RESTful事务基础概念
在RESTful架构中,事务操作主要涉及GET和PUT两种基本操作。GET操作用于获取资源的值,不会改变资源版本;而PUT操作则用于更新资源,会使资源版本发生变化。当一个事务进行GET操作时,它依赖于该资源的当前版本;若进行PUT操作,生成的资源版本则依赖于该事务。
若事务中止并执行撤销逻辑,其所有PUT操作都必须被撤销,这会使资源获得新的版本,因为撤销操作类似于一次普通的新更新。在RESTful模型中,采用基于影子的更新方式,避免了锁撤销的复杂性。
### 1.1 事务依赖与版本管理
事务之间的依赖关系可通过依赖图来表示,理论上依赖图可看作一个时间序列。应用ACID属性的主要结论是:无环的依赖图意味着事务的隔离执行。违反隔离性的风险通常与各种依赖循环相关。
与传统事务类似,REST循环依赖可分为三种通用形式:
- 当两个或多个事务访问同一资源时,可能会产生该资源的两个或多个不同版本(丢失更新)。
- 事务可能使用资源的过期版本(脏读和不可重复读)。
### 1.2 事务操作与生命周期
为了保证事务的一致性和隔离性,在GET和PUT资源时,需要应用SLOCK(共享锁)和XLOCK(排他锁),并在对资源的依赖过期时释放这些锁。因此,模型应支持对资源的GET、PUT、XLOCK、SLOCK、UNLOCK等主要操作,以及BEGIN、COMMIT、ROLLBACK等通用操作。
一个事务是从BEGIN操作开始,以COMMIT或ROLLBACK操作结束的一系列操作序列。为简化事务模型,BEGIN、COMMIT和ROLLBACK可通过其他操作来定义,最终仅保留GET、PUT、LOCK和UNLOCK操作。
简单事务由GET、PUT、XLOCK、SLOCK和UNLOCK操作组成。每个事务T都可转换为等效的简单事务,具体转换规则如下:
1. 丢弃BEGIN操作。
2. 若事务以COMMIT操作结束,将该操作替换为一系列UNLOCK操作:<UNLOCK A | if SLOCK A or XLOCK A appears in T for any resource A>。
3. 若事务以ROLLBACK操作结束,将该操作替换为一系列PUT操作,然后是UNLOCK操作:<PUT A | if PUT A appears in T for any resource A> ||<UNLOCK A | if SLOCK A or XLOCK A appears in T for any resource A>。
### 1.3 事务的特性
事务具有一些重要特性:
- 格式良好的事务:所有GET、PUT和UNLOCK操作都由锁覆盖,且每个锁操作最终都有对应的UNLOCK操作。
- 两阶段事务:所有LOCK操作都在UNLOCK操作之前。两阶段事务T有一个增长阶段(获取锁)和一个收缩阶段(释放锁)。
## 2. 历史记录与锁的兼容性
### 2.1 历史记录的定义
历史记录是一组事务操作的顺序合并序列,用$H = \langle\langle t, a, r\rangle_i | i = 1, \ldots, n\rangle$表示。每个历史步骤$\langle t, a, r\rangle$是事务t对资源r执行的操作a。历史记录列出了操作成功完成的顺序。
串行历史记录是一次只执行一个事务的历史记录,不存在并发问题,也不会出现数据不一致和脏数据查看问题。
### 2.2 合法历史记录与锁兼容性
合法历史记录是遵守锁约束的历史记录。锁兼容性规则限制了允许的历史记录集合,具体如下表所示:
| 前一个锁的模式 | 新锁的模式 | 共享锁 | 排他锁 |
| --- | --- | --- | --- |
| 共享锁 | 是 | 否 | |
| 排他锁 | 否 | 否 | |
例如,在图4中展示了三种历史记录:
- 历史记录1是串行历史记录,显然是合法的,因为每个事务按顺序执行,不会有锁冲突。
- 历史记录2是非串行合法历史记录,T1和T2之间没有不兼容的锁,因为T2仅在T1执行UNLOCK后才对资源B应用XLOCK。
- 历史记录3是非串行且不合法的历史记录,资源B已被T1加XLOCK,但T2又对同一资源应用XLOCK,这违反了锁兼容性规则,导致T1的PUT操作覆盖了T2的PUT操作,即出现“丢失更新”的情况。
### 2.3 RESTful HTTP中的锁
为处理HTTP并发挑战,引入了锁的概念,且不影响Web的始终可用和向后兼容特性。理想情况下,任何可由HTTP服务器提供的资源都应是可锁定资源(R)。为了实现这一点,可以让资源链接到锁集合和事务集合,或者创建包含这些信息的自定义HTTP头。
锁资源(R - L)由专用媒体类型表示,包含以下元素:
| 元素 | 描述 |
| --- | --- |
| ResourceURI | 指向该锁影响的资源的链接 |
| TransactionURI | 指向控制该锁的事务的链接 |
| Type | 锁的类型,“S”或“X” |
| PrevLockURI | 指向锁序列中前一个锁的链接 |
| Timestamp | 服务器授予锁的时间戳 |
| Duration | 锁的有效时间间隔 |
| ConditionalRepresentationURI | 锁提交后资源将生效的表示的链接 |
| InitialRepresentationURI | 锁资源初始状态的链接 |
锁的类型分为XLOCK(排他锁)和SLOCK(共享锁)。放置新锁时,服务器需验证用户是否为锁所引用事务的所有者。锁的有效时间取决于服务器为客户端提供保证的最大时长,锁过期后将被中止。为避免违反两阶段锁协议(2PL),若一个事务的某个锁过期,该事务的所有其他锁也将过期。
在锁生效期间,直接的PUT和DELETE操作会返回“405 Method Not Allowed”HTTP响应,而GET请求仍应成功返回。这一行为保持了向后兼容性,若客户端需要对资源的未来状态有更多保证,应尝试放置锁。
### 2.4 资源锁集合与事务相关资源
资源锁集合(R - Lc)包含按锁兼容性规则排序的锁,以Atom Feed形式表示。客户端可通过GET请求检索锁集合,判断资源是否被锁定;可通过POST方法提交新锁。
事务(T)资源由专用媒体类型表示,包含TransactionCollectionURI、OwnerURI和TransactionLockCollectionURI,用于标识执行事务所需的信息集合。事务集合(Tc)是新事务提交的资源,通过POST操作创建新事务并返回其表示的URI,该资源本身不能通过GET访问。事务锁集合(T - Lc)包含与特定事务相关的锁的链接,以Atom feed格式呈现。客户端不能直接中止单个锁,必须通过T - Lc中止事务的所有锁,这相当于中止事务。
事务锁集合(T - Lc)的可用操作如下表所示:
| 操作 | 描述 |
| --- | --- |
| GET | 返回与事务相关的锁集合 |
| DELETE | 中止相关事务的所有锁,仅由事务所有者执行 |
### 2.5 可恢复性与条件资源表示
基于回滚定理,若一个事务解锁排他锁后执行“回滚”操作,且该事务未退化,则可能导致“虫洞”问题。为实现回滚,模型不直接在实际资源上存储潜在更新,而是使用锁定数据的影子,即条件资源表示。
初始资源表示(R - L - IR)与锁定资源具有相同的媒体类型,用于存储初始状态,与锁一起存档,以便在锁提交时表示更改并支持回滚。条件资源表示(R - L - CR)也是与锁定资源相同的媒体类型,本质上是XLOCK提交后将应用于资源的状态。
条件资源表示(R - L - CR)的可用操作如下表所示:
| 操作 | 描述 |
| --- | --- |
| GET | 返回若相关XLOCK提交将被提交的表示 |
| PUT | 创建新的条件状态,在关联的XLOCK提交时替换锁定资源的当前状态 |
| DELETE | 删除条件状态,若XLOCK提交,将不执行写操作 |
### 2.6 模型概述
定义了所有资源类型后,形成了一个相互连接的网络。只需拥有资源R的URI,就足以定位网络中的所有其他资源。由于安全原因,事务集合(Tc)资源没有GET能力,给定事务T的URI仅作为事务所有者在Tc上执行初始POST操作的响应返回。
相关资
0
0
复制全文
相关推荐






