1

我正在研究SQL,需要知道某个事务方案是否可序列化。我理解确定这一点的方法是制作一个图表,其中交易作为节点和节点之间的方向,如果图表是循环的,那么该方案是不可序列化的。但它是什么意思,又是什么决定了图中是否存在从一个事务到另一个事务的有向边?在这种情况下,序列化与将对象写入磁盘的序列化类型相同吗?

感谢您的任何见解

4

2 回答 2

4

事务序列化与对象序列化无关。可序列化事务隔离级别在完全实现后,可确保任何一组并发可序列化事务的行为与某些串行(一次一个)执行序列一致——就好像这些事务已经在一个时间。这意味着如果你能证明一个数据库事务在单独运行时会做正确的事情,它会在任何可序列化事务的组合中做正确的事情,或者它会在序列化失败时回滚以便可以重试从头开始。

可序列化事务隔离可以通过多种方式实施。最常见的方案是严格的两阶段锁定 (S2PL)。这个很常见,以至于您经常在 SO 上看到仅根据此技术讨论事物的答案。还有乐观并发控制 (OCC)、可序列化快照隔离 (SSI) 等。

9.1 之前的 PostgreSQL 版本、某些配置中的 MS SQL Server 以及所有版本的 Oracle 实际上并不提供可序列化的事务。它们让您请求它们,但实际上提供了快照隔离。从 9.1 开始的 PostgreSQL 版本在请求可序列化事务隔离时使用SSI 。

不可能彻底讨论这些技术中的任何一种在 SO 答案中是如何工作的,但总结一下上面提到的技术:

  • 在 S2PL 下,事务中的每个写入都获取一个不能与任何东西共享的锁,事务中的每个读取都获取一个可以与其他读取共享但不能与写入共享的锁。读锁需要覆盖扫描索引中的“空白”。锁一直保持到事务结束,并随着事务的工作对其他事务可见而自动释放。如果阻塞创建了一个循环,这称为“死锁”,循环中涉及的事务之一被回滚。

  • 在 OCC 下,事务跟踪它使用的数据,而不锁定它。当请求事务提交时,事务检查是否有任何其他事务修改了它的任何数据并提交。如果是这样,则提交请求失败并且工作被回滚。

  • 在 SSI 下,写入会相互阻塞,但读取不会阻塞写入,写入不会阻塞读取。跟踪读写依赖关系以寻找可见性模式,这将在明显的执行顺序中创建一个循环。如果发现“危险结构”,这意味着可能执行明显执行顺序的循环,则回滚可能循环中涉及的事务之一。它更像 OCC 而不是 S2PL,但在更高的争用下没有那么多的回滚。

全面披露:我与麻省理工学院的 Dan RK Ports 合作,在 PostgreSQL 9.1 中实现了新的基于 SSI 的可序列化事务。

于 2012-05-11T11:48:50.013 回答
2

序列化意味着事务可以以串行方式执行,一个接一个(与对象序列化无关),基本上一个事务是可序列化的方式,如果图是循环的,那么它是不可序列化的,并且存在一些冲突的风险,在这里你的隔离级别将有助于决定是否应该以串行方式执行事务,即第一个然后另一个或者是否它应该尝试以交错的方式执行它,希望没有冲突。它不是一个完整的答案,但我希望这会有所帮助。

于 2012-05-11T08:19:06.027 回答