当 Oracle ACID 不完全遵守“隔离”属性时,它如何兼容?
Posted
技术标签:
【中文标题】当 Oracle ACID 不完全遵守“隔离”属性时,它如何兼容?【英文标题】:How is Oracle ACID compliant when it does not honour 'isolation' property fully? 【发布时间】:2019-11-10 15:56:00 【问题描述】:声明:Oracle 不支持 ACID 属性中的隔离属性。 根据Wikipedia page on ACID
“隔离确保事务的并发执行使数据库处于与按顺序执行事务时相同的状态。”
只有在事务是可序列化的情况下才会发生这种情况。是的,Oracle 有一个称为 Serializable 的事务级别,但它不是真正的可串行化,只是快照隔离。
阅读https://blog.dbi-services.com/oracle-serializable-is-not-serializable/ 摘自 Wiki 页面的快照隔离 (https://en.wikipedia.org/wiki/Snapshot_isolation)
“尽管快照隔离与可串行化有区别,但 Oracle 有时将其称为可串行化”。
存在较弱的隔离级别,但不足以保证事务的顺序会导致按顺序执行时会获得的结果。为了保证这一点,可序列化是必须的。
Q1)由于 Oracle 不提供它(它的可串行化不是真正的),它不能 100% 遵守隔离。那它怎么能被称为 ACID 兼容呢?
Q2) 看起来 Oracle 在隔离方面受到了宽大处理。这种宽大处理是否也扩展到其他数据库?
Q3)如果我们采取无情的立场并说(隔离意味着 100% 的隔离 - 不亚于被接受),甲骨文关于符合 ACID 的声明会不会落空?其他关系数据库呢?他们能否晋级,还是会像甲骨文一样落空?
【问题讨论】:
Postgres 实现了真正的可序列化隔离级别。但据我了解,ACID 不是(仅)提供序列化隔离级别。我认为支持A
和I
- read committed
已经足够了。
您的问题是基于误解。 ACID 的首字母缩写词没有精确的含义。阅读它出现的论文——他们只是从 4 个项目开始,作为理解和总结可序列化调度的实现的非正式亮点,即实现就像它们被序列化一样的并发事务,即通过 SERIALIZABLE 实现 SQL 的含义。 Wikipedia ACID 页面只是对论文失实陈述的另一个不合理的鹦鹉学舌。 Oracle SERIALIZABLE 不是“可序列化的”并声称它“符合 ACID”是似是而非的。
什么“宽大”?任何人都可以提出任何要求,没有授权允许虚假陈述或误导。什么“Oracle 声称符合 ACID”?请报价。 PS 请每个问题问一个问题。请不要索要外部资源或其属性的列表。请在考虑提出问题之前进行研究。您发现什么可以回答您自己的(主题)问题?请参阅How to Ask 和投票箭头鼠标悬停文本。
@philipxy- 只有在进行了深入研究之后,我才在这里提出一个问题。这是最后的手段。我的问题不仅仅是甲骨文。它一般是关于关系数据库的。(它们真的符合 ACID 吗?)。我们不能在 cmets 部分问很多问题,因此,我在帖子中问了所有问题。什么“Oracle 声称符合 ACID”?请报价 - 这是否意味着 Oracle 不符合 ACID 标准?但是,许多关系数据库(我认为包括 Oracle)都自豪地佩戴着 ACID 合规性徽章。 ACID 与 RDBMS 密切相关。
【参考方案1】:
除了 SNAPSHOT,SQL Server 还具有 SERIALIZABLE。但是,至少在 SQL Server 中,对于大多数实际用途而言,SERIALIZABLE 是无用的,因为它太贵了,而且不是很有效。并且您对实际需要序列化的少数事务使用特殊构造(即一次运行一个)。
SERIALIZABLE 代价高昂,因为事务排序是通过消除并发的某种组合以及通过生成运行时故障(死锁)来完成的。两者都非常昂贵和麻烦。
SERIALIZABLE 并不是真正有效,因为实际上并没有完成完全的事务隔离。这样做需要每个事务独占锁定它读取的所有数据,以防止两个事务读取相同的数据,然后写入。 经典示例是运行两个会话
SELECT salary FROM emp where id = 1
然后,根据客户端中已有的值计算一个新的值,然后
UPDATE emp set salary = :newSalary
使这项工作正常进行的唯一方法是在第一次读取时设置排他锁,这样第二次会话也无法读取。
在 Oracle 中,这是通过 SELECT ... FOR UPDATE 完成的,而在 SQL Server 中,则使用 UPDLOCK 提示来完成。或者使用显式的“应用程序锁”、Oracle 的 DMBS_LOCK 或 SQL Server 的 sp_getapplock。
【讨论】:
SSI(“Serializable Snapshot Isolation”)的开销取决于实现,它不是原理所固有的。例如,在 Postgres 中,仅“快照隔离”(“可重复读取”)的 SSI 开销非常低 阅读blog.dbi-services.com/oracle-serializable-is-not-serializable。看起来 Postgres 正在自动提供 Oracle 无法提供的可序列化性。 “看来只有 PostgreSQL(版本 >= 9.1)才能保证真正的可序列化而不加锁。” @David Browne - Microsoft - 你能在我的帖子中回答 Q3 吗?只是为了争论,让我们假设我们想要 100% 的隔离,并且不会采取任何低于此的措施。 “SERIALIZABLE 并不是真正有效,因为实际上并没有完成完全的事务隔离。” - 但是,这就是可序列化的意思。不是吗? Oracle 的可序列化可能无法完成,但 Postgres 等其他人似乎正在这样做。阅读我上面的评论。 如果 Postgres 检测到更新异常,它仍然会中止事务。它可能具有更好的 SERIALIZABILE 实现,因为它可以以更少的中断防止更多异常。但成本仍然存在。以上是关于当 Oracle ACID 不完全遵守“隔离”属性时,它如何兼容?的主要内容,如果未能解决你的问题,请参考以下文章