2010-11-01 105 views
1

我讀到Oracle維護行版本來處理併發。我想在非常大的實時數據庫上運行更新查詢,但此更新作業必須更改該行的最新版本。有沒有辦法通過SQL更新最新版本的行?

這可能通過PL/SQL或簡單的SQL?

編輯下面**

讓我清楚的情況下,我們面臨着一個非常大的數據庫在現實生活中的問題。我們的客戶是一家知名的手機服務提供商。

我們的數據庫有一個表格,用於管理客戶手機帳戶上剩餘的當前餘額記錄。在表格的其他列中,一列存儲完成的再充值量,另一列存儲剩餘的當前有效餘額。

我們有兩個獨立的PL/SQL腳本。客戶爲手機充值並更新餘額時,會自動觸發一個腳本。

第二個腳本是關於從客戶帳戶中扣除某些費用。這是一項批量工作,因爲它適用於所有客戶。該腳本計劃在一天的特定時間間隔內運行。當此腳本運行時,它會在內存中加載50,000條記錄,更新某些列並執行批量更新回到表格。

問題發生的事情是這樣的:

一位顧客,他的ID是101,聯繫他在當地商店買東西,他的手機充電。他支付金額。但直到他的手機即將充電時,第二個腳本的預定時間纔開始了第二個腳本。第二個腳本在內存中加載了50,000個客戶的記錄。在這個內存記錄中,也是這個客戶的記錄之一。

直到第二個腳本的批量更新完成時,第一個腳本成功爲客戶的帳戶充值。

現在發生了什麼是實際的表,列:「CurrentAccountBalance」被更新爲150,但其第二腳本工作過客戶的舊的平衡,即在內存中的記錄,100

第二個腳本必須從列中扣除10:「CurrentAccountBalance」。根據實際工作,當客戶的「CurrentAccountBalance」應爲140時,此問題使他的餘額爲90.

現在該如何處理這個問題。

+0

你說的是閃回,Oracle的臨時訪問? – 2010-11-01 18:13:25

+0

編號純SQL更新語句。 – RKh 2010-11-01 18:17:13

+0

您正試圖查看來自其他會話的未提交數據?然後在提交之前更新它!? – 2010-11-01 18:25:35

回答

4

我想你想要的是什麼反正發生如果你UPDATE

甲骨文確實保留了一段時間的舊數據,但只是爲了支持一致的讀取。也就是說,讀操作只能看到事務開始時的狀態 - 即使數據在此期間被覆蓋。它被稱爲多版本併發控制,可以通過事務隔離級別來控制。

您可以通過選擇`FOR UPDATE明確要求最近的一個;爲記錄添加鎖定,以便其他人無法在此期間更新它(直到您的交易結束)。

但是,如果您需要編寫任何內容(例如,UPDATE),Oracle會在最新版本上運行總是

+0

請檢查OP中的實際情況。 – RKh 2010-11-02 08:01:01

+0

我已經在運行,只是通過您的更新掠過。這可能是一個競爭條件?所以我在上面添加了一些關於FOR UPDATE的內容。 – 2010-11-02 08:19:25

1

正如@Markus建議的那樣,您有一個競爭條件。如果您在更新表中的行之前將記錄加載到內存中並處理它們,並且其他內容可能會在嘗試更新它們的同時嘗試更新它們,那麼您需要在處理它們時鎖定它們。 (我假設你正在做的事情太複雜了,不能做一個簡單的一步更新)。像這樣的東西會工作:

DECLARE 
    CURSOR c is SELECT * FROM current_balance_table FOR UPDATE; 
BEGIN 
    FOR r IN c LOOP 
     /* Do whatever calculations you need */ 
     new_value := r.CurrantAccountBalance - 10; 
     UPDATE current_balance_table SET CurrentAccountBalance = new_value 
     WHERE CURRENT OF c; 
    END LOOP: 
END; 

現在的問題是,所有的記錄都被鎖定爲循環的持續時間,所以你在店內的客戶要麼無法更新自己的平衡,或將有一個日誌在更新生效之前等待 - 儘管如此,它會對您存儲的更新值起作用。所以你必須將光標分成小塊,平衡腳本的性能和對其他嘗試更新同一個表的人的影響。

一種選擇是使用外部遊標來選擇所有未鎖定的客戶,然後在該行被計算和更新時鎖定該客戶的餘額記錄。您必須在每個內部循環之後提交才能釋放該行的鎖定。這涉及到更多的鎖定/解鎖和每次行更新後提交減慢了很多事情。但它最大限度地減少了對店內個人客戶的影響,因爲一次只鎖定一行,鎖定的時間最短。所以,你需要找到合適的平衡點。

+0

目前我們正在鎖定,但我想知道任何有效的替代方案。 – RKh 2010-11-02 09:41:10

相關問題