久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Oracle、MySQL、DB2并發(fā)控制機(jī)制的異同是什么

共計(jì) 4802 個(gè)字符,預(yù)計(jì)需要花費(fèi) 13 分鐘才能閱讀完成。

這篇文章主要介紹“Oracle、MySQL、DB2 并發(fā)控制機(jī)制的異同是什么”,在日常操作中,相信很多人在 Oracle、MySQL、DB2 并發(fā)控制機(jī)制的異同是什么問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”O(jiān)racle、MySQL、DB2 并發(fā)控制機(jī)制的異同是什么”的疑惑有所幫助!接下來,請(qǐng)跟著丸趣 TV 小編一起來學(xué)習(xí)吧!

數(shù)據(jù)庫的數(shù)據(jù)一致性支持機(jī)制:事務(wù)、鎖、日志。

首先我們看看什么是事務(wù)。

一、事務(wù)

事務(wù):又稱為交易,訪問數(shù)據(jù)庫系統(tǒng)的可恢復(fù)的最小單元。

1、事務(wù)的 ACID

原子性 (Atomicity):事務(wù)為一個(gè)整體的工作單元,事務(wù)對(duì)數(shù)據(jù)庫的操作要么全部執(zhí)行,要么全部取消;

一致性 (Consistency):事務(wù)完成時(shí),所有數(shù)據(jù)都保持一致狀態(tài);

隔離性 (Isolation):事務(wù)所做的修改必須與其他事務(wù)所做的修改隔離。事務(wù)查看數(shù)據(jù)時(shí)數(shù)據(jù)的狀態(tài)要么為其他事務(wù)修改之前要么為其他事務(wù)修改之后,不會(huì)為中間狀態(tài)。即多個(gè)事務(wù)不能同時(shí)修改同一份數(shù)據(jù);

持久性 (Durability):事務(wù)提交后,對(duì)數(shù)據(jù)庫所做的修改會(huì)永久保存。

2、事務(wù)的初始化和終止

事務(wù)在可執(zhí)行的 SQL 第一次執(zhí)行時(shí)會(huì)自動(dòng)初始化,事務(wù)一旦初始化,就必須終止 (COMMIT 或 ROLLBACK)。

1) 關(guān)于事務(wù)的 COMMIT 和 ROLLBACK

多數(shù)情況下,事務(wù)通過執(zhí)行 COMMIT 或 ROLLBACK 終止事務(wù)。執(zhí)行 COMMIT 語句后,事務(wù)初始化后對(duì)數(shù)據(jù)庫做出的所有改變都會(huì)變成永久的; 執(zhí)行 ROLLBACK 語句后,事務(wù)初始化后對(duì)數(shù)據(jù)庫做出的所有改變都會(huì)被撤銷,數(shù)據(jù)庫返回事務(wù)開始之前的狀態(tài)。

2) 關(guān)于不成功的事務(wù)的結(jié)果

上面說了當(dāng)事務(wù)被 COMMIT 或 ROLLBACK 終止語句后會(huì)發(fā)生什么,如果事務(wù)完成之前系統(tǒng)發(fā)生故障,會(huì)發(fā)生什么? 這種情況下,數(shù)據(jù)庫管理器將撤銷所有未 COMMIT 的修改,從而恢復(fù)數(shù)據(jù)的一致性。

DB2 中通過 ACTIVE  LOG 日志文件實(shí)現(xiàn)撤銷修改。日志文件包含關(guān)于事務(wù)執(zhí)行的每個(gè)語句的信息,以及事務(wù)是否被成功 COMMIT 或 ROLLBACK 的信息。

MySQL 和 Oracle 利用 undo log 撤銷修改。undo  log 記錄了行的修改操作,執(zhí)行事務(wù)中由于某種原因失敗,或使用 ROLLBACK 時(shí),就可以利用 undo log 將數(shù)據(jù)恢復(fù)到修改之前的樣子。

3、事務(wù)的隔離級(jí)別

1) 潛在問題

事務(wù)為什么需要多種可以設(shè)置的隔離級(jí)別呢? 通常,鎖可以實(shí)現(xiàn)并發(fā)操作中事務(wù)的隔離,保證數(shù)據(jù)的一致性。鎖提高了并發(fā)性能,但會(huì)帶來潛在的問題:

臟讀:當(dāng)前事務(wù)可以讀到另外一個(gè)事務(wù)中未提交的數(shù)據(jù)。

不可重復(fù)讀:在一個(gè)事務(wù)內(nèi)讀到的同一條數(shù)據(jù)是不一樣的。

幻讀:事務(wù) A 在相同條件下第二次讀取時(shí)讀到新插入的數(shù)據(jù)。

丟失更新:一個(gè)事務(wù)的更新操作會(huì)被另一個(gè)事務(wù)的更新操作所覆蓋,從而導(dǎo)致數(shù)據(jù)的不一致。例如:

事務(wù) T1 將行記錄修改為 V1,事務(wù) T1 未提交。

事務(wù) T2 將行記錄修改為 V2,事務(wù) T2 未提交。

事務(wù) T1 提交。

事務(wù) T2 提交。

在當(dāng)前數(shù)據(jù)庫的鎖機(jī)制下不會(huì)導(dǎo)致理論意義上的丟失更新問題,但是實(shí)際上在所有多用戶計(jì)算機(jī)系統(tǒng)環(huán)境下都有可能產(chǎn)生這個(gè)問題。例如:

事務(wù) T1 查詢一行數(shù)據(jù),放入本地內(nèi)存,顯示給 User1。

事務(wù) T2 查詢一行數(shù)據(jù),放入本地內(nèi)存,顯示給 User2。

User1 修改這行記錄,更新數(shù)據(jù)庫并提交。

User2 修改這行記錄,更新數(shù)據(jù)庫并提交。

這些問題往往和系統(tǒng)數(shù)據(jù)庫的使用方式和形態(tài)有關(guān)。而設(shè)置事務(wù)的隔離級(jí)別,就是根據(jù)不同的場(chǎng)景來解決以上問題。比如上面所說的丟失更新問題,隔離級(jí)別中 SELECT hellip;FOR  UPDATE 即帶有更新意圖讀的時(shí)候,步驟 1、2 都是要上寫鎖的,避免丟失更新的問題。下面詳解數(shù)據(jù)庫的隔離級(jí)別及其加鎖方式。

2) 數(shù)據(jù)庫的隔離級(jí)別及其加鎖方式

① SQL 標(biāo)準(zhǔn)定義的四個(gè)隔離級(jí)別

READ UNCOMMITTED:未提交讀。事務(wù)可以看到其他事務(wù)所有未提交的數(shù)據(jù)。讀取數(shù)據(jù)不加鎖;

READ COMMITTED:提交讀。事務(wù)只可以看到其他事務(wù)已經(jīng)提交的數(shù)據(jù);

REPEATABLE READ:重復(fù)度。鎖定事務(wù)引用的符合檢索條件的部分行,其他事務(wù)不可修改這些行,但可執(zhí)行 INSERT 操作。即可能出現(xiàn)幻讀;

SERIALIZABLE:可串行化。強(qiáng)制的進(jìn)行排序,在每個(gè)讀數(shù)據(jù)行上添加鎖,所有事務(wù)依次逐個(gè)執(zhí)行,事務(wù)之間不會(huì)產(chǎn)生干擾。事務(wù)提交后釋放鎖。會(huì)導(dǎo)致大量超時(shí)現(xiàn)象和鎖競(jìng)爭(zhēng)。

② 四種隔離級(jí)別會(huì)導(dǎo)致的問題

隔離級(jí)別臟讀不可重復(fù)讀幻讀 READ UNCOMMITTED radic; radic; radic;READ COMMITTED times; radic; radic;REPEATABLE READ times; times; radic;SERIALIZABLE times; times; times;

③ 數(shù)據(jù)庫中的隔離級(jí)別

DB2 中的隔離級(jí)別:

CS(Cursor  Stability):游標(biāo)穩(wěn)定性。逐行鎖定數(shù)據(jù),該行數(shù)據(jù)未修改時(shí),鎖定解除,繼續(xù)加鎖讀取下一行,該行數(shù)據(jù)有修改時(shí),則該行鎖定持續(xù)到事務(wù)終止。CS 的程序不能查看其他程序未 COMMIT 的更改。

CS 提供了最大的并發(fā)性。但同一事務(wù)同一游標(biāo)被處理兩次,可能返回不同的結(jié)果,即不可重復(fù)度;CS 程序讀取的行上有任何可更新游標(biāo)時(shí),其他任何應(yīng)用程序都不能更新或刪除該行。

CS 是 DB2 默認(rèn)的隔離級(jí)別。在需要最大并行性但只能看到其他程序已 COMMIT 的數(shù)據(jù)時(shí)使用。

RR(Repeatable  Read):可重復(fù)讀。RR 會(huì)鎖定事務(wù)引用的所有行,直到 COMMIT。其他程序不能修改該數(shù)據(jù),如果一條數(shù)據(jù)被訪問兩次,返回相同的結(jié)果。

RR 是最高隔離級(jí)別,可以最好的保證數(shù)據(jù)一致性,但是大量鎖定數(shù)據(jù),會(huì)導(dǎo)致并發(fā)度大大降低,同時(shí)有可能超過系統(tǒng)定義的持有鎖數(shù)量的限制。

相當(dāng)于標(biāo)準(zhǔn)定義隔離級(jí)別中的 SERIALIZABLE 相比,上鎖范圍一致。

RS(Read  Stability):讀穩(wěn)定性。RS 會(huì)鎖定事務(wù)引用的所有行中符合檢索條件的部分行。其他程序不可修改,但可執(zhí)行 INSERT 操作,所以同一事務(wù)中,如果數(shù)據(jù)被訪問兩次可能返回新插入的數(shù)據(jù),即幻讀,但是舊數(shù)據(jù)不會(huì)有改變。

相比 RR,RS 鎖定數(shù)據(jù)的數(shù)量大大減少,并發(fā)度得到提升。比較適合在并發(fā)環(huán)境下運(yùn)行,但只適合在同一事物中不會(huì)多次發(fā)出相同查詢,或不要求相同查詢獲得相同結(jié)果的程序,避免發(fā)生幻讀。

DB2 的 RS 和標(biāo)準(zhǔn)定義隔離級(jí)別中的 REPEATABLE READ(重復(fù)讀) 類似,避免了臟讀,但是會(huì)出現(xiàn)幻讀問題。

UR(Uncommitted  Read):未提交讀,也就是“臟”讀。UR 不會(huì)加任何鎖,可以讀數(shù)據(jù)庫中的任何數(shù)據(jù),包含已修改但未 COMMIT 的數(shù)據(jù)。讀的數(shù)據(jù)可能與真實(shí)的數(shù)據(jù)有一定差距。

UR 級(jí)別最常用于只讀表上的查詢,或者只執(zhí)行查詢且不關(guān)心能否讀到其他程序未 COMMIT 的數(shù)據(jù)時(shí)常用。

UR 相當(dāng)于標(biāo)準(zhǔn)定義隔離級(jí)別中的 READ UNCOMMITTED(未提交讀)。

MySQL 支持標(biāo)準(zhǔn)定義的四種隔離級(jí)別,默認(rèn)的隔離級(jí)別為 REPEATABLE  READ(重復(fù)度),但是與標(biāo)準(zhǔn) SQL 不同的是,MySQL 的 InnoDB 存儲(chǔ)引擎在 REPEATABLE READ 的隔離級(jí)別下,使用 Next-Key  Lock(鎖定一個(gè)范圍,并鎖定記錄本身),因此避免幻讀的產(chǎn)生。所以說 InnoDB 存儲(chǔ)引擎在 REPEATABLE  READ 的隔離級(jí)別下已經(jīng)能保證事務(wù)的隔離性要求,即達(dá)到 SQL 標(biāo)準(zhǔn)的 SERIALIZABLE 隔離級(jí)別。

Oracle 數(shù)據(jù)庫支持 READ COMMITTED(提交讀) 和 SERIALIZABLE 這兩種事務(wù)隔離級(jí)別。默認(rèn)的隔離級(jí)別是 READ  COMMITTED(提交讀)。

二、鎖

事務(wù)隔離級(jí)別是并發(fā)控制的整體解決方案,其實(shí)際上是綜合利用各種類型的鎖和行版本控制來解決并發(fā)問題。

這里我們主要看數(shù)據(jù)庫中的基本鎖。

1、鎖的類型

S-LOCK:共享鎖。又叫讀鎖,當(dāng)用戶要進(jìn)行數(shù)據(jù)的讀取時(shí),對(duì)數(shù)據(jù)加上共享鎖。共享鎖可以同時(shí)加多個(gè);

X-LOCK:排他鎖。又叫寫鎖。SQL  INSERT/UPDATE/DELETE 語句執(zhí)行時(shí)會(huì)上 X -LOCK。排他鎖只可以加一個(gè),和其他的排他鎖共享鎖都相斥;

U-LOCK:修改鎖。CURSOR SELECT 有 UPDATE OF 子句時(shí),F(xiàn)ETCH 時(shí)對(duì)讀出的記錄,會(huì)上 U -LOCK。

DB2、MySQL、Oracle 都支持 S -LOCK 和 X -LOCK,DB2 還支持 U -LOCK。

2、事務(wù)隔離級(jí)別中讀數(shù)據(jù)時(shí)的鎖類型

如上,數(shù)據(jù)庫在各種隔離級(jí)別下,SQL 執(zhí)行 INSERT/UPDATE/DELETE 語句時(shí)都會(huì)上 X -LOCK,那么在讀數(shù)據(jù)時(shí)如何上鎖呢?

DB2 和 MySQL 在 Uncommitted Read 隔離級(jí)別下,不加任何鎖。

1)DB2

DB2 在另外三種 CS、RR、RS 隔離級(jí)別時(shí),SELECT 語句,或 CURSOR SELECT 無 UPDATE  OF 子句,F(xiàn)ETCH 時(shí)對(duì)讀出的記錄會(huì)上 S -LOCK,不同的是,CS 在讀取下一行數(shù)據(jù)時(shí)就釋放上一行的鎖,RR、RS 在事務(wù)提交時(shí)才釋放鎖;SELET hellip;FOR  UPDATE 對(duì)讀取的數(shù)據(jù)都是加 U 鎖,CS 在讀取下一行數(shù)據(jù)時(shí)就釋放上一行的鎖,RR、RS 在事務(wù)提交時(shí)才釋放鎖;INSERT/UPDATE/DELETE 語句執(zhí)行時(shí)會(huì)上 X -LOCK,CS、RR、RS 都是在事務(wù)提交時(shí)才釋放 X 鎖,其他事務(wù)不能對(duì)已鎖定的行加任何鎖。

2)MySQL

MySQL 的 InnoDB 在隔離級(jí)別 READ COMMITED 和 REPEATABLE  READ(MySQL 的默認(rèn)隔離級(jí)別) 下 SELECT 時(shí)不上鎖,即 MySQL 中的一致性非鎖定讀; 只有指定 SELECT hellip;LOCK IN SHARE  MOAD 才對(duì)記錄上 S -LOCK,SERIALIZABLE 隔離級(jí)別下 SELECT 對(duì)記錄上 S -LOCK; 三種隔離級(jí)別下,SELET hellip;FOR  UPDATE 對(duì)讀取的數(shù)據(jù)都是加 X 鎖,在 MySQL 中叫做一致性鎖定讀。

3)Oracle

Oracle 中只支持 READ COMMITED 和 SERIALIZABLE 隔離級(jí)別。這兩種隔離級(jí)別下的鎖機(jī)制和 InnoDB 一致。Oracle 中不需要 READ  UNCOMMITTED 隔離級(jí)別,是因?yàn)?READ UNCOMMITTED 主要功能是提高只讀時(shí)的并發(fā)性,而 Oracle 在 READ  COMMITED 隔離級(jí)別下使用一致性非鎖定讀也有同樣的功能。

3、一致性非鎖定讀

隔離級(jí)別 READ COMMITED 和 REPEATABLE READ(MySQL 的默認(rèn)隔離級(jí)別) 都使用一致性非鎖定讀, SELECT 時(shí)不上鎖,那么如何保證事務(wù)的隔離性呢? 這兩種隔離級(jí)別采用快照數(shù)據(jù)的方式保證隔離性。讀取時(shí)對(duì)于上了 X 鎖的數(shù)據(jù),都會(huì)去讀取行的一個(gè)快照數(shù)據(jù)。快照數(shù)據(jù)是指該行的之前版本的數(shù)據(jù),通過 undo 段實(shí)現(xiàn)。而 undo 段用來在事務(wù)中回滾數(shù)據(jù),因此快照數(shù)據(jù)本身沒有額外的開銷。

READ COMMITED 和 REPEATABLE  READ 兩種隔離級(jí)別在讀快照數(shù)據(jù)時(shí)的區(qū)別是,RC 總是讀取最新的快照數(shù)據(jù),所以可能會(huì)發(fā)生不可重復(fù)讀,即第二次讀取的數(shù)據(jù)和第一次不一致; 而 RR 總是讀取事務(wù)開始時(shí)的快照,所以不會(huì)發(fā)生不可重復(fù)度。

非鎖定讀機(jī)制不會(huì)等待行上 X 鎖的釋放,極大的提高了數(shù)據(jù)庫的并發(fā)性。是 InnoDB 的默認(rèn)讀取方式。

三、小結(jié)

并發(fā)控制在保證數(shù)據(jù)一致性的前提下提供最大的并發(fā)性,而保證數(shù)據(jù)一致性的前提就是保證事務(wù)的隔離性,事務(wù)的隔離性和并發(fā)性是成反比的,隔離級(jí)別越高,并發(fā)性越低。所以程序要視并發(fā)性和隔離性的輕重選擇隔離級(jí)別。

到此,關(guān)于“Oracle、MySQL、DB2 并發(fā)控制機(jī)制的異同是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注丸趣 TV 網(wǎng)站,丸趣 TV 小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-08-03發(fā)表,共計(jì)4802字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請(qǐng)注明出處。
評(píng)論(沒有評(píng)論)
主站蜘蛛池模板: 南靖县| 玉树县| 西藏| 手游| 旺苍县| 舞阳县| 武隆县| 达拉特旗| 调兵山市| 紫云| 大竹县| 韶关市| 兴和县| 泗阳县| 墨竹工卡县| 台南市| 信阳市| 怀柔区| 石城县| 台北县| 木里| 扬州市| 昌邑市| 江川县| 常熟市| 新蔡县| 新丰县| 吉首市| 阳新县| 吉安市| 抚州市| 文安县| 常州市| 青冈县| 怀仁县| 宁河县| 博罗县| 稷山县| 名山县| 汤阴县| 斗六市|