我正在研究SQL,需要知道某个事务方案是否可序列化。我理解确定这个的方法是制作一个图表,其中事务作为节点之间的节点和方向,如果图形是循环的,则该方案不可序列化。但它是什么意思,是什么决定了图表中从一个交易到另一个交易是否存在有针对性的边缘?在这种情况下,序列化是否与将对象写入磁盘的序列化相同?
感谢您的任何见解
答案 0 :(得分:2)
序列化意味着事务可以以串行的方式一个接一个地执行(与对象序列化无关),基本上是一个可序列化的事务,如果无论这些事务是否被交错,结果就好像它们被执行了一样以串行的方式,如果图形是循环的,那么它不可序列化并且存在一些冲突的风险,这里你的隔离级别将有助于决定事务应该以串行方式执行,这意味着第一个然后是其他或者它应该尝试以交错的方式执行它,希望没有冲突。 它不是一个完整的答案,但我希望这会有所帮助。
答案 1 :(得分:2)
事务序列化与对象序列化无关。可完全实现时,可序列化事务隔离级别可确保任何并发可序列化事务集的行为与某些串行(一次一个)执行序列一致 - 就好像交易一次只运行一次。这意味着如果您可以证明数据库事务在单独运行时会做正确的事情,它将在任何可序列化事务的混合中执行正确的操作,或者它将回滚序列化失败,以便可以重试从一开始。
可以通过多种方式强制执行可序列化的事务隔离。最常见的方案是严格的两阶段锁定(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的可序列化事务。