![](/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.