sql - 如何知道事务方案何时可序列化?

标签 sql transactions

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

感谢您的任何见解

最佳答案

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

可以通过多种方式强制执行可序列化事务隔离。最常见的方案是严格的两相锁定 (S2PL)。这个很常见,您经常会在 SO 上看到仅就此技术讨论问题的答案。还有乐观并发控制(OCC)、可序列化快照隔离(SSI)等。

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

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

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

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

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

完全披露:我与 Dan R.K. 合作。 MIT 的端口,用于在 PostgreSQL 9.1 中实现新的基于 SSI 的可序列化事务。

关于sql - 如何知道事务方案何时可序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10547673/

相关文章:

java - 带有嵌套事务的 Spring JpaTransactionManager

java - Arjuna JTA 事务意外回滚

transactions - 如何将电子支付从一个银行账户自动支付到 20,000 个其他银行账户?

spring - 如何在配置文件中将刷新模式设置为 "COMMIT"?

sql - 如何统计每一行出现的次数并将其显示在另一个表中?

php - 从 MySQL 数据中删除/隐藏添加的反斜杠

sql - 查询获取最后 n 行(不包括最后一行)

sql - 在 R 脚本中使用 R 变量的 where 子句以在 SQL 语句中使用它

hibernate - 为什么有不同类型的事务管理器?

c# - 使用名称单独超链接创建 Gridview