![](/img/trans.png)
[英]How can I diagnose a long running transaction and save the data if possible?
[英]For a long running report, do I use a read only or serializable transaction?
我有一个用SQL * Plus编写的长期运行报告,带有几个SELECT。 我想更改事务隔离级别以获得对数据的一致视图。 我发现了两种可能的解决方
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
和
SET TRANSACTION READ ONLY;
我将哪一个用于报告?为什么? 任何性能影响? 对其他会话的任何影响(这是一个生产数据库)。
请注意,问题是关于上面的两个选项,而不是关于各种隔离级别。
SERIALIZABLE
是否阻止对我的报告查询的表进行更改?
我天真地认为READ ONLY
对数据库的压力稍微小一些,因为没有预期的数据变化。 这是真的,Oracle是否利用了这一点?
在Oracle中,您可以在SERIALIZABLE
和READ COMMITTED
之间进行选择。
READ ONLY
与serializable相同,关于它看到其他会话更改的方式,但不允许表修改。
使用SERIALIZABLE
或READ ONLY
您的查询将无法在序列化事务开始后看到对数据库所做的更改。
使用READ COMMITTED
,您的查询将无法在查询的生命周期内看到对数据库所做的更改。
SERIALIZABLE READ COMMITTED ANOTHER SESSION
(or READ ONLY)
Change 1
Transaction start Transaction start
Change 2
Query1 Start Query1 Start
... ... Change 3
Query1 End Query1 End
Query2 Start Query2 Start
... ... Change 4
Query2 End Query2 End
使用serializable,query1和query2只能看到change1。
使用read committed,query1将看到更改1和2,query2将看到更改1到3。
有趣的问题。 我相信SERIALIZABLE
和READ ONLY
对数据库具有相同的“税”,并且会比READ COMITTED
(通常是默认值)更大。 您或其他并发用户不应存在显着的性能差异。 但是,如果数据库由于UNDO
表空间太小或者undo_retention
太短(默认值为15分钟)而无法保持读取一致性,那么查询将因臭名昭着的ORA-01555
失败。 其他用户不应该经历痛苦,除非有其他用户尝试做类似的事情。 询问您的DBA设置的undo_retention
参数是什么, UNDO
表空间有多大以及它是否可自动扩展。
如果存在类似大小的非prod环境,请尝试使用不同的隔离级别对查询进行基准测试。 在第一个查询运行后检查数据库中的用户锁(或者如果您没有足够的权限,请检查DBA)。 多次进行此测试,每次测试具有不同的隔离级别。 基本上,文档很棒,但实验通常更快,更明确。
最后,为了彻底避开这个问题,你有没有办法将你的两个查询合并为一个,也许是一个UNION ALL
? 这在很大程度上取决于您的两个查询的关系。 如果是这样,那么问题就没有实际意义了。 一个组合查询将是自洽的。
..很多问题。
对于仅使用选择的会话,两个隔离级别都是等效的。 所以你选择哪一个并没有什么不同。 (READ只是不是ANSI标准)
除了性能影响之外,除非您在此会话中提交任何内容(仅限SERIALIZABLE),否则其他会话或具有事务隔离级别SERIALIZABLE或READ ONLY的会话内的其他会话不会产生任何影响。
您在这两个隔离级别内的选择性能不应该有所不同,因为您不在那里更改数据。
使用这两个隔离级别之一与Oracle默认READ COMMITTED进行比较的性能不是最佳的。 特别是如果在SERIALIZABLE交易期间大量数据发生变化,您可能会遇到性能下降。
我天真地认为READ ONLY对数据库的压力稍微小一些,因为没有预期的数据变化。 这是真的,Oracle是否利用了这一点?
=>不。
希望这可以帮助。
Oracle文档中的这篇文章提供了很多关于不同事务隔离级别的详细信息。 http://docs.oracle.com/cd/B10501_01/server.920/a96524/c21cnsis.htm
在您的示例中,听起来您想要Serializable
。 Oracle在读取数据时不会阻塞,因此在只读查询中使用serializable不应阻止其他事务中的查询或crud操作。
如其他答案中所述,使用read only
隔离级别与使用可serializable
类似,只是read only
不允许插入,更新或删除。 但是,由于read only
不是SQL标准并且可serializable
,所以我会在这种情况下使用serializable
,因为它应该完成同样的事情,将来很清楚其他开发人员,并且因为Oracle提供了更详细的文档,关于什么是与可serializable
隔离级别的“幕后”一起使用。
以下是关于可序列化的一些信息,来自上面引用的文章(我在方括号中添加了一些注释以便澄清):
可序列化隔离模式通过防止幻像[读取来自其他事务的插入]和不可重复读取[读取来自其他事务的更新/删除]来提供更高的一致性,并且在读/写事务多次执行查询时可能很重要。
与可锁定块以进行读取和写入的其他可序列化隔离实现不同, Oracle提供非阻塞查询[非阻塞读取]和行级锁定的精细粒度,这两者都减少了写/写争用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.