一個(gè)簡(jiǎn)單的小案例帶你理解MySQL中的事務(wù)
事務(wù)又叫做TCL,全稱是transaction control language,意思是事務(wù)控制語(yǔ)言。這篇文章還是屬于我的mysql基礎(chǔ)文章,在前面我們介紹了下面這些基礎(chǔ)知識(shí):
- 數(shù)據(jù)庫(kù)的增查改刪操作
- 數(shù)據(jù)表的增查改刪操作
- 數(shù)據(jù)的增查改刪操作
- 數(shù)據(jù)的約束以及增查改刪
- Mysql中的內(nèi)置函數(shù)
這篇文章還是基礎(chǔ)系列的文章,主要是介紹mysql中的事務(wù),為了保持文章的完整性,就算你沒(méi)有看過(guò)之前的教程也沒(méi)問(wèn)題。
一、事務(wù)的理解
張三有1000塊錢(qián),李四也有1000塊錢(qián),張三給李四500,還剩下500,李四此時(shí)就有1500。我們想象著會(huì)執(zhí)行下面的mysql語(yǔ)句:
- update table user set money=500 where name = "張三";
- update table user set money=1500 where name = "李四";
但是在計(jì)算機(jī)中可能會(huì)不一樣??赡苌厦嬲Z(yǔ)句執(zhí)行了下面的沒(méi)有執(zhí)行,因此為了保證兩條語(yǔ)句要么都執(zhí)行,要么都不執(zhí)行,這時(shí)候就用到了事務(wù)。
事務(wù)的意思是一條或者是一組語(yǔ)句組成一個(gè)單元,這個(gè)單元要么全部執(zhí)行,要么全不執(zhí)行。
事務(wù)具有四個(gè)特性,也是面試??嫉乃膫€(gè)特性ACID:
- A(原子性Atomicity):原子性指的是事務(wù)是一個(gè)不可分割的,要么都執(zhí)行要么都不執(zhí)行。
- C(一致性Consistency):事務(wù)必須使得數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài),到另外一個(gè)一致性狀態(tài)。
- I(隔離性Isolation):指的是一個(gè)事務(wù)的執(zhí)行,不能被其他的事務(wù)所干擾。
- D(持久性Durability):持久性指的是一個(gè)事務(wù)一旦提交了之后,對(duì)數(shù)據(jù)庫(kù)的改變就是永久的。
二、創(chuàng)建一個(gè)事務(wù)
事務(wù)其實(shí)可以劃分為兩大類:隱式的事務(wù)和顯示的事務(wù):
- 隱式的事務(wù)很簡(jiǎn)單,比如我們的insert、delete、update、select這些語(yǔ)句都是隱式的事務(wù)。
- 顯示的事務(wù)指的是帶有很明顯的開(kāi)始和結(jié)束的標(biāo)記,下面就來(lái)創(chuàng)建一個(gè)顯示的事務(wù)。
步驟一:禁用步驟提交功能
- set autocommit = 0;
步驟二:開(kāi)啟一個(gè)事務(wù)
- start transaction;
步驟三:sql語(yǔ)句
- update table user set money=500 where name = "張三";
- update table user set money=1500 where name = "李四";
步驟四:結(jié)束事務(wù)
commit(提交)或者是rollback(回滾)。如果確定我們的語(yǔ)句沒(méi)有問(wèn)題,那么我們就可以commit,如果認(rèn)為我們的語(yǔ)句有問(wèn)題,那就rollback。
在這里新建了一個(gè)表,然后插入了兩條數(shù)據(jù)。下面我們使用事務(wù),來(lái)更新一下:
在這里我們使用的是commit進(jìn)行提交。當(dāng)然如果突然發(fā)現(xiàn)我們之前的操作有錯(cuò)誤,那就可以使用rollback。
三、事務(wù)的隔離級(jí)別
上面的事務(wù)在單個(gè)情況下一般不會(huì)出現(xiàn)什么問(wèn)題,但是如果同時(shí)運(yùn)行多個(gè),就會(huì)出現(xiàn)問(wèn)題了。我們知道并發(fā)操作總是會(huì)出現(xiàn)各種各樣的問(wèn)題,對(duì)于事務(wù)來(lái)說(shuō)就會(huì)出現(xiàn)下面三個(gè)典型的問(wèn)題:
(1)臟讀
有倆事務(wù)T1,T2。如果T1讀了一條數(shù)據(jù),這條數(shù)據(jù)是T2更新的但是還沒(méi)提交,突然T2覺(jué)得不合適進(jìn)行事務(wù)回滾了,也就是不提交了。此時(shí)T1讀的數(shù)據(jù)就是無(wú)效的數(shù)據(jù)。
(2)不可重復(fù)讀
有倆事務(wù)T1,T2。如果T1讀了一條數(shù)據(jù),之后T2更新了這條數(shù)據(jù),T1再次讀取就發(fā)現(xiàn)值變了。
(3)幻讀
有倆事務(wù)T1,T2。如果T1讀了一條數(shù)據(jù),之后T2插入了一些新的數(shù)據(jù),T1再次讀取就會(huì)多出現(xiàn)一些數(shù)據(jù)。
如何去解決這些問(wèn)題呢?既然多個(gè)事務(wù)同時(shí)運(yùn)行不好,那就把他們隔離開(kāi)來(lái)。這時(shí)候就用到了事務(wù)的隔離性。
mysql默認(rèn)的事務(wù)隔離級(jí)別為repeatable-read,Oracle默認(rèn)的是read-committed,
想要去演示事務(wù)的隔離級(jí)別也很簡(jiǎn)單,只需要開(kāi)啟兩個(gè)客戶端演示就OK了,在這里就不說(shuō)了。