簡體   English   中英

對於長時間運行的報告,我是使用只讀還是可序列化的事務?

[英]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中,您可以在SERIALIZABLEREAD COMMITTED之間進行選擇。

READ ONLY與serializable相同,關於它看到其他會話更改的方式,但不允許表修改。

使用SERIALIZABLEREAD 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。

有趣的問題。 我相信SERIALIZABLEREAD ONLY對數據庫具有相同的“稅”,並且會比READ COMITTED (通常是默認值)更大。 您或其他並發用戶不應存在顯着的性能差異。 但是,如果數據庫由於UNDO表空間太小或者undo_retention太短(默認值為15分鍾)而無法保持讀取一致性,那么查詢將因臭名昭着的ORA-01555失敗。 其他用戶不應該經歷痛苦,除非有其他用戶嘗試做類似的事情。 詢問您的DBA設置的undo_retention參數是什么, UNDO表空間有多大以及它是否可自動擴展。

如果存在類似大小的非prod環境,請嘗試使用不同的隔離級別對查詢進行基准測試。 在第一個查詢運行后檢查數據庫中的用戶鎖(或者如果您沒有足夠的權限,請檢查DBA)。 多次進行此測試,每次測試具有不同的隔離級別。 基本上,文檔很棒,但實驗通常更快,更明確。

最后,為了徹底避開這個問題,你有沒有辦法將你的兩個查詢合並為一個,也許是一個UNION ALL 這在很大程度上取決於您的兩個查詢的關系。 如果是這樣,那么問題就沒有實際意義了。 一個組合查詢將是自洽的。

..很多問題。

  1. 對於僅使用選擇的會話,兩個隔離級別都是等效的。 所以你選擇哪一個並沒有什么不同。 (READ只是不是ANSI標准)

  2. 除了性能影響之外,除非您在此會話中提交任何內容(僅限SERIALIZABLE),否則其他會話或具有事務隔離級別SERIALIZABLE或READ ONLY的會話內的其他會話不會產生任何影響。

  3. 您在這兩個隔離級別內的選擇性能不應該有所不同,因為您不在那里更改數據。

  4. 使用這兩個隔離級別之一與Oracle默認READ COMMITTED進行比較的性能不是最佳的。 特別是如果在SERIALIZABLE交易期間大量數據發生變化,您可能會遇到性能下降。

  5. 我天真地認為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM