溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL基礎(chǔ)——事務(wù)隔離級別

發(fā)布時(shí)間:2020-06-30 10:37:07 來源:網(wǎng)絡(luò) 閱讀:601 作者:一個(gè)笨小孩 欄目:數(shù)據(jù)庫

事務(wù)是DBMS得執(zhí)行單位。它由有限得數(shù)據(jù)庫操作序列組成得。但不是任意得數(shù)據(jù)庫操作序列都能成為事務(wù)。一般來說,事務(wù)是必須滿足4個(gè)條件(ACID)

 ①:原子性(Autmic):事務(wù)在執(zhí)行性,要做到“要么不做,要么全做!”,就是說不允許事務(wù)部分得執(zhí)行。即使因?yàn)楣收隙故聞?wù)不能完成,在rollback時(shí)也要消除對數(shù)據(jù)庫得影響!

 ②:一致性(Consistency):事務(wù)操作之后,數(shù)據(jù)庫所處的狀態(tài)和業(yè)務(wù)規(guī)則是一致的;比如a,b賬戶相互轉(zhuǎn)賬之后,總金額不變!

 ③:隔離性(Isolation):如果多個(gè)事務(wù)并發(fā)執(zhí)行,應(yīng)像各個(gè)事務(wù)獨(dú)立執(zhí)行一樣!

 ④:持久性(Durability):事務(wù)提交后被持久化到數(shù)據(jù)庫.


1、MYSQL的事務(wù)處理主要有兩種方法。

①:用BEGIN,ROLLBACK,COMMIT來實(shí)現(xiàn)

   開始:START TRANSACTION或BEGIN語句可以開始一項(xiàng)新的事務(wù)

   提交:COMMIT可以提交當(dāng)前事務(wù),是變更成為永久變更

   回滾:ROLLBACK可以回滾當(dāng)前事務(wù),取消其變更


②:直接用set來改變mysql的自動(dòng)提交模式

    MYSQL默認(rèn)是自動(dòng)提交的,也就是你提交一個(gè)QUERY,它就直接執(zhí)行!


2、事務(wù)的隔離級別:

   SQL標(biāo)準(zhǔn)定義了4類隔離級別,包括了一些具體規(guī)則,用來限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發(fā)處理,并擁有更低的系統(tǒng)開銷。


①:Read Uncommitted(讀取未提交內(nèi)容)

  在該隔離級別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌墑e好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。


②:Read Committed(讀取提交內(nèi)容)

  這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡單定義:一個(gè)事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變。這種隔離級別 也支持所謂的不可重復(fù)讀(Nonrepeatable Read),因?yàn)橥皇聞?wù)的其他實(shí)例在該實(shí)例處理其間可能會(huì)有新的commit,所以同一select可能返回不同結(jié)果。


③:Repeatable Read(可重讀)

  這是MySQL的默認(rèn)事務(wù)隔離級別,它確保同一事務(wù)的多個(gè)實(shí)例在并發(fā)讀取數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行。不過理論上,這會(huì)導(dǎo)致另一個(gè)棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時(shí),會(huì)發(fā)現(xiàn)有新的“幻影” 行。InnoDB和Falcon存儲(chǔ)引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問題。


④:Serializable(可串行化) 

  這是最高的隔離級別,它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖。在這個(gè)級別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競爭。


---注意:這四種隔離級別采取不同的鎖類型來實(shí)現(xiàn),若讀取的是同一個(gè)數(shù)據(jù)的話,就容易發(fā)生問題。例如:


    ①:臟讀(Drity Read):某個(gè)事務(wù)已更新一份數(shù)據(jù),另一個(gè)事務(wù)在此時(shí)讀取了同一份數(shù)據(jù),由于某些原因,前一個(gè)RollBack了操作,則后一個(gè)事務(wù)所讀取的數(shù)據(jù)就會(huì)是不正確的。


    ②:不可重復(fù)讀(Non-repeatable read):在一個(gè)事務(wù)的兩次查詢之中數(shù)據(jù)不一致,這可能是兩次查詢過程中間插入了一個(gè)事務(wù)更新的原有的數(shù)據(jù)。


    ③:幻讀(Phantom Read):在一個(gè)事務(wù)的兩次查詢中數(shù)據(jù)筆數(shù)不一致,例如有一個(gè)事務(wù)查詢了幾列(Row)數(shù)據(jù),而另一個(gè)事務(wù)卻在此時(shí)插入了新的幾列數(shù)據(jù),先前的事務(wù)在接下來的查詢中,就會(huì)發(fā)現(xiàn)有幾列數(shù)據(jù)是它先前所沒有的。  SQL標(biāo)準(zhǔn)定義了4類隔離級別,包括了一些具體規(guī)則,用來限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發(fā)處理,并擁有更低的系統(tǒng)開銷。


3、修改MySQL的默認(rèn)事務(wù)隔離級別:

   -----注意:MySQL默認(rèn)的事務(wù)隔離級別: REPEATABLE-READ(可重讀)


①:修改事務(wù)隔離級別的語法:

 SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}


注意:默認(rèn)的行為(不帶session和global)是為下一個(gè)(未開始)事務(wù)設(shè)置隔離級別。如果你使用GLOBAL關(guān)鍵字,語句在全局對從那點(diǎn)開始創(chuàng)建的所有新連接(除了不存在的連接)設(shè)置默認(rèn)事務(wù)級別。你需要SUPER權(quán)限來做這個(gè)。使用SESSION 關(guān)鍵字為將來在當(dāng)前連接上執(zhí)行的事務(wù)設(shè)置默認(rèn)事務(wù)級別。 任何客戶端都能自由改變會(huì)話隔離級別(甚至在事務(wù)的中間),或者為下一個(gè)事務(wù)設(shè)置隔離級別。


②:用下列語句查詢?nèi)趾蜁?huì)話事務(wù)隔離級別:


SELECT @@global.tx_isolation; 

SELECT @@session.tx_isolation; 

SELECT @@tx_isolation; 


③:設(shè)置事務(wù)隔離級別:

-----在my.cnf配置文件修改:

  [mysqld]

 transaction-isolation = READ-COMMITTED


-----使用命令修改:

mysql> set global transaction isolation level read committed;

mysql> set session transaction isolation level read committed;


start transaction; //打開事務(wù) 


擴(kuò)展知識(shí):

“兩條不同的插入語句導(dǎo)致的死鎖:”

如果沒有特別的需求,可以設(shè)置MySQL的默認(rèn)隔離級別設(shè)置為read-committed級別,這樣可以避免很多不必要的問題;也是解決死鎖的一種方法;


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI