Oracle 数据库中的 READ_COMMITTED 和 SERIALIZABLE 隔离级别有啥区别?

Posted

技术标签:

【中文标题】Oracle 数据库中的 READ_COMMITTED 和 SERIALIZABLE 隔离级别有啥区别?【英文标题】:What's the difference between READ_COMMITTED and SERIALIZABLE isolation levels in Oracle database?Oracle 数据库中的 READ_COMMITTED 和 SERIALIZABLE 隔离级别有什么区别? 【发布时间】:2015-01-29 10:18:08 【问题描述】:

在阅读了一些有关交易的文件后,我现在完全糊涂了。让我先解释一下我的场景。

我有一个批量读取,从表中读取数据 (SELECT) 查询大约需要 3 分钟。同时另一个线程尝试执行 INSERT/UPDATE/DELETE。它抛出一个错误,说“无法获取事务”(因为我的数据源的默认事务为 8 (SERIALIZABLE))。

为了允许 INSERT/UPDATE/DELETE 执行,我将事务设置为 READ_UNCOMMITTED(根本没有锁(读/写/范围))。但是当我执行我的程序时,它抛出了一个错误,说唯一支持的事务是 READ_COMMITTED 和 SERIALIZABLE。

当我进一步调查时,我发现 Oracle 引入了 事务隔离 类型的 snapshot 隔离,它通过采取 snapshot 事务期间数据库的快照,在那里提供一致的数据。

根据上述声明,我可以使用 READ_COMMITTED 的事务类型,但是到目前为止,***完全混淆了我对以下声明的理解:

快照隔离在Oracle[2][3][4]中称为“可序列化”模式 和 9.1、[5][6][7] 之前的 PostgreSQL 版本,这可能会导致 与“真正的可序列化”模式混淆。有论据 支持和反对该决定;很明显,用户必须 注意区别以避免可能出现的不受欢迎的异常 数据库系统逻辑中的行为。

所以现在我的问题是:

    从 Oracle 的角度来看,SERIALIZABLE 和 READ_COMMITTED 有什么区别? 如果采取快照隔离并且对于两个不同的事务和更新相同的条目会引发错误,Oracle 是否会引发错误? 如果我的理解有任何偏离,请告诉我。

【问题讨论】:

【参考方案1】:

1.READ COMMITTED 隔离级别:默认级别。每个查询(事务内)只能看到在该查询开始之前提交的数据。因此,如果您在同一事务中两次运行相同的查询,您可能会看到不同的结果和幻像。

SERIALIZABLE 隔离级别:每个查询(在事务内)只能看到在该事务开始之前提交的数据,以及在事务本身中所做的更改。所以,这里没有幻影。

2.在Oracle 中,快照隔离被称为serializable。所以,是一样的。当可序列化事务尝试更新或删除另一个在可序列化事务开始后提交的事务修改的数据时,Oracle 将抛出错误。

其实更多信息可以在here找到。

【讨论】:

所以不会有任何锁持有? Oracle 中没有读锁。但在同时修改数据的情况下,当然可以使用锁。 我还有一个问题,在可序列化隔离部分它说可序列化隔离是合适的,相对长时间运行的事务主要是只读的?在这种情况下,插入/更新/删除将被阻止直到事务提交? @KarthikPrasad,是的,长时间运行的事务应该(如果可能的话)主要是只读的,因为修改 same 行的长时间运行的事务需要回滚每个时间(在可序列化模式下)。只读事务不会阻塞任何其他事务,也不会等待它们。

以上是关于Oracle 数据库中的 READ_COMMITTED 和 SERIALIZABLE 隔离级别有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

让oracle数据库中的约束失效

在oracle怎样更新表中的数据

oracle10g 中的还原点

oracle中列中的数据求和

Oracle中的锁

如何将oracle数据库中的数据如何导入到sqlserver