3 回答

TA貢獻(xiàn)1951條經(jīng)驗(yàn) 獲得超3個(gè)贊
給出問(wèn)題的最佳方法是使用純 SQL,例如:
update employees set
salary = salary * .9
很難想象需要對(duì) SQL 無(wú)法處理的員工數(shù)據(jù)執(zhí)行某些操作。
如果由于某種不良設(shè)計(jì)的怪癖,您確實(shí)需要對(duì) SQL 絕對(duì)無(wú)法執(zhí)行的員工類型數(shù)據(jù)執(zhí)行某些操作,那么您將打開一個(gè)指向行集的游標(biāo)并遍歷它,同步進(jìn)行更新,這樣您只需執(zhí)行一次傳遞數(shù)據(jù)。
在偽代碼中:
cursor = forUpdate ("select for update * from employees")
while (cursor.next()) {
cursor.salary = cursor.salary * .9
}
這是最簡(jiǎn)單且執(zhí)行速度可能最快的方法。
—-
關(guān)于日志記錄
它只有 2M 行,這是一個(gè)“小”數(shù)量,因此大多數(shù) DB 可以在單個(gè)事務(wù)中處理它。但是,如果沒(méi)有,請(qǐng)?zhí)砑右粋€(gè) where 子句,例如,where id between <start> and <end>如果使用 shell 腳本方法,則將過(guò)程分塊到可記錄的數(shù)量的查詢中。
如果使用代碼方法,大多數(shù)數(shù)據(jù)庫(kù)允許您在保持游標(biāo)打開的情況下提交,因此只需每 10K 行左右提交一次。
關(guān)于鎖定
與日志記錄類似的方面。在事務(wù)期間,此類查詢中的所有行都被鎖定。鑒于跑步需要那么長(zhǎng)時(shí)間,請(qǐng)選擇一個(gè)安靜的時(shí)間跑步。如果這真的很重要,請(qǐng)分塊,但要意識(shí)到鎖定是不可避免的。

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超9個(gè)贊
您可以做的一件事是使用生產(chǎn)者/消費(fèi)者類型模型,其中您有一個(gè)線程工作以向其他線程提供要更新的記錄。這樣您就不必?fù)?dān)心重復(fù)處理。

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超6個(gè)贊
我會(huì)加載到這個(gè)表中,然后為狀態(tài)添加一列。默認(rèn)情況下,您可以將此列設(shè)置為“未處理”。一旦線程開始處理該員工,它會(huì)將狀態(tài)更改為“正在處理”,然后在完成后最終將狀態(tài)切換為“已處理”。
擁有 3 個(gè)這樣的狀態(tài)還可以讓您將其用作鎖,防止處理發(fā)生兩次。
添加回答
舉報(bào)