声明:Oracle不支持ACID属性中的隔离属性。 按照Wikipedia page on ACID
“隔离确保并发执行事务使数据库保持与顺序执行事务所获得的状态相同的状态。”
仅当事务可序列化时才可能发生。是的,Oracle有一个称为“可序列化”的事务级别,但它不是真正的可序列化性,仅是快照隔离。
阅读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%隔离-不会接受更多的隔离),那么Oracle声称符合ACID的主张会不会成片?那么其他关系数据库呢?他们将能够晋级,还是会像甲骨文那样失败?
答案 0 :(得分:-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。