數(shù)據(jù)庫-事物

一衬廷、事務(wù)定義

Transaction
事務(wù):一個(gè)最小的不可再分的工作單元鲤氢;通常一個(gè)事務(wù)對(duì)應(yīng)一個(gè)完整的業(yè)務(wù)(例如銀行賬戶轉(zhuǎn)賬業(yè)務(wù)搀擂,該業(yè)務(wù)就是一個(gè)最小的工作單元)
一個(gè)完整的業(yè)務(wù)需要批量的DML(insert、update卷玉、delete)語句共同聯(lián)合完成
事務(wù)只和DML語句有關(guān)哨颂,或者說DML語句才有事務(wù)。這個(gè)和業(yè)務(wù)邏輯有關(guān)相种,業(yè)務(wù)邏輯不同威恼,DML語句的個(gè)數(shù)不同

二、轉(zhuǎn)賬操作理解事務(wù)

關(guān)于銀行賬戶轉(zhuǎn)賬操作蚂子,賬戶轉(zhuǎn)賬是一個(gè)完整的業(yè)務(wù)沃测,最小的單元,不可再分————————也就是說銀行賬戶轉(zhuǎn)賬是一個(gè)事務(wù)
以下是銀行賬戶表t_act(賬號(hào)食茎、余額)蒂破,進(jìn)行轉(zhuǎn)賬操作

actno       balance
1           500
2           100

轉(zhuǎn)賬操作

update t_act set balance=400 where actno=1;
update t_act set balance=200 where actno=2;

以上兩臺(tái)DML語句必須同時(shí)成功或者同時(shí)失敗。最小單元不可再分,當(dāng)?shù)谝粭lDML語句執(zhí)行成功后乞娄,并不能將底層數(shù)據(jù)庫中的第一個(gè)賬戶的數(shù)據(jù)修改,只是將操作記錄了一下租漂;這個(gè)記錄是在內(nèi)存中完成的喇伯;當(dāng)?shù)诙lDML語句執(zhí)行成功后喊儡,和底層數(shù)據(jù)庫文件中的數(shù)據(jù)完成同步。若第二條DML語句執(zhí)行失敗稻据,則清空所有的歷史操作記錄艾猜,要完成以上的功能必須借助事務(wù)

三、事務(wù)四大特征(ACID)

原子性(A):事務(wù)是最小單位捻悯,不可再分
一致性(C):事務(wù)要求所有的DML語句操作的時(shí)候匆赃,必須保證同時(shí)成功或者同時(shí)失敗
隔離性(I):事務(wù)A和事務(wù)B之間具有隔離性
持久性(D):是事務(wù)的保證,事務(wù)終結(jié)的標(biāo)志(內(nèi)存的數(shù)據(jù)持久到硬盤文件中)

四今缚、關(guān)于事務(wù)的一些術(shù)語

開啟事務(wù):Start Transaction
事務(wù)結(jié)束:End Transaction
提交事務(wù):Commit Transaction
回滾事務(wù):Rollback Transaction

五算柳、和事務(wù)相關(guān)的兩條重要的SQL語句(TCL)

commit:提交
rollback:回滾

六、事務(wù)開啟的標(biāo)志姓言?事務(wù)結(jié)束的標(biāo)志瞬项?

開啟標(biāo)志:

  • 任何一條DML語句(insert、update何荚、delete)執(zhí)行囱淋,標(biāo)志事務(wù)的開啟

結(jié)束標(biāo)志(提交或者回滾):

  • 提交:成功的結(jié)束,將所有的DML語句操作歷史記錄和底層硬盤數(shù)據(jù)來一次同步
  • 回滾:失敗的結(jié)束餐塘,將所有的DML語句操作歷史記錄全部清空

注意:mysql需要手動(dòng)打開事物(start transaction;)

七绎橘、事物與數(shù)據(jù)庫底層數(shù)據(jù)

在事物進(jìn)行過程中,未結(jié)束之前唠倦,DML語句是不會(huì)更改底層數(shù)據(jù)称鳞,只是將歷史操作記錄一下,在內(nèi)存中完成記錄稠鼻。只有在事物結(jié)束的時(shí)候冈止,而且是成功的結(jié)束的時(shí)候,才會(huì)修改底層硬盤文件中的數(shù)據(jù)

八候齿、在MySQL中熙暴,事務(wù)提交與回滾

在MySQL中,默認(rèn)情況下慌盯,事務(wù)是自動(dòng)提交的周霉,也就是說,只要執(zhí)行一條DML語句就開啟了事物亚皂,并且提交了事務(wù)

以上的自動(dòng)提交機(jī)制是可以關(guān)閉的
對(duì)t_user進(jìn)行提交和回滾操作
提交操作(事務(wù)成功)
start transaction
DML語句
commit

mysql> start transaction;#手動(dòng)開啟事務(wù)
mysql> insert into t_user(name) values('pp');
mysql> commit;#commit之后即可改變底層數(shù)據(jù)庫數(shù)據(jù)
mysql> select * from t_user;

id name
1 jay
2 man
3 pp

3 rows in set (0.00 sec)

回滾操作(事務(wù)失敗)
start transaction
DML語句
rollback

mysql> start transaction;
mysql> insert into t_user(name) values('yy');
mysql> rollback;
mysql> select * from t_user;

id name
1 jay
2 man
3 pp

3 rows in set (0.00 sec)

九俱箱、事務(wù)四大特性之一————隔離性(isolation)

事物A和事物B之間具有一定的隔離性
隔離性有隔離級(jí)別(4個(gè))
讀未提交:read uncommitted
讀已提交:read committed
可重復(fù)讀:repeatable read
串行化:serializable

1、 read uncommitted

  • 事物A和事物B灭必,事物A未提交的數(shù)據(jù)狞谱,事物B可以讀取到
  • 這里讀取到的數(shù)據(jù)叫做“臟數(shù)據(jù)”
  • 這種隔離級(jí)別最低乃摹,這種級(jí)別一般是在理論上存在,數(shù)據(jù)庫隔離級(jí)別一般都高于該級(jí)別

公司發(fā)工資了跟衅,領(lǐng)導(dǎo)把5000元打到singo的賬號(hào)上孵睬,但是該事務(wù)并未提交,而singo正好去查看賬戶伶跷,發(fā)現(xiàn)工資已經(jīng)到賬掰读,是5000元整,非常高 興叭莫×字В可是不幸的是,領(lǐng)導(dǎo)發(fā)現(xiàn)發(fā)給singo的工資金額不對(duì)食寡,是2000元,于是迅速回滾了事務(wù)廓潜,修改金額后抵皱,將事務(wù)提交,最后singo實(shí)際的工資只有 2000元辩蛋,singo空歡喜一場(chǎng)呻畸。

出現(xiàn)上述情況,即我們所說的臟讀 悼院,兩個(gè)并發(fā)的事務(wù)伤为,“事務(wù)A:領(lǐng)導(dǎo)給singo發(fā)工資”、“事務(wù)B:singo查詢工資賬戶”据途,事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù)绞愚。

當(dāng)隔離級(jí)別設(shè)置為Read uncommitted 時(shí),就可能出現(xiàn)臟讀颖医,如何避免臟讀位衩,請(qǐng)看下一個(gè)隔離級(jí)別。

2熔萧、read committed

  • 事物A和事物B糖驴,事物A提交的數(shù)據(jù),事物B才能讀取到
  • 這種隔離級(jí)別高于讀未提交
  • 換句話說佛致,對(duì)方事物提交之后的數(shù)據(jù)贮缕,我當(dāng)前事物才能讀取到
  • 這種級(jí)別可以避免“臟數(shù)據(jù)”
  • 這種隔離級(jí)別會(huì)導(dǎo)致“不可重復(fù)讀取”
  • Oracle默認(rèn)隔離級(jí)別

singo拿著工資卡去消費(fèi),系統(tǒng)讀取到卡里確實(shí)有2000元俺榆,而此時(shí)她的老婆也正好在網(wǎng)上轉(zhuǎn)賬感昼,把singo工資卡的2000元轉(zhuǎn)到另一賬戶,并在 singo之前提交了事務(wù)罐脊,當(dāng)singo扣款時(shí)抑诸,系統(tǒng)檢查到singo的工資卡已經(jīng)沒有錢烂琴,扣款失敗,singo十分納悶蜕乡,明明卡里有錢奸绷,為 何......

出現(xiàn)上述情況,即我們所說的不可重復(fù)讀 层玲,兩個(gè)并發(fā)的事務(wù)号醉,“事務(wù)A:singo消費(fèi)”、“事務(wù)B:singo的老婆網(wǎng)上轉(zhuǎn)賬”辛块,事務(wù)A事先讀取了數(shù)據(jù)畔派,事務(wù)B緊接了更新了數(shù)據(jù),并提交了事務(wù)润绵,而事務(wù)A再次讀取該數(shù)據(jù)時(shí)线椰,數(shù)據(jù)已經(jīng)發(fā)生了改變。

當(dāng)隔離級(jí)別設(shè)置為Read committed 時(shí)尘盼,避免了臟讀憨愉,但是可能會(huì)造成不可重復(fù)讀。

大多數(shù)數(shù)據(jù)庫的默認(rèn)級(jí)別就是Read committed卿捎,比如Sql Server , Oracle配紫。如何解決不可重復(fù)讀這一問題,請(qǐng)看下一個(gè)隔離級(jí)別

3午阵、repeatable read

  • 事務(wù)A和事務(wù)B躺孝,事務(wù)A提交之后的數(shù)據(jù),事務(wù)B讀取不到
  • 事務(wù)B是可重復(fù)讀取數(shù)據(jù)
  • 這種隔離級(jí)別高于讀已提交
  • 換句話說底桂,對(duì)方提交之后的數(shù)據(jù)植袍,我還是讀取不到
  • 這種隔離級(jí)別可以避免“不可重復(fù)讀取”,達(dá)到可重復(fù)讀取
  • 比如1點(diǎn)和2點(diǎn)讀到數(shù)據(jù)是同一個(gè)
  • MySQL默認(rèn)級(jí)別
  • 雖然可以達(dá)到可重復(fù)讀取籽懦,但是會(huì)導(dǎo)致“幻像讀”

singo的老婆工作在銀行部門奋单,她時(shí)常通過銀行內(nèi)部系統(tǒng)查看singo的信用卡消費(fèi)記錄。有一天猫十,她正在查詢到singo當(dāng)月信用卡的總消費(fèi)金額 (select sum(amount) from transaction where month = 本月)為80元览濒,而singo此時(shí)正好在外面胡吃海塞后在收銀臺(tái)買單,消費(fèi)1000元拖云,即新增了一條1000元的消費(fèi)記錄(insert transaction ... )贷笛,并提交了事務(wù),隨后singo的老婆將singo當(dāng)月信用卡消費(fèi)的明細(xì)打印到A4紙上宙项,卻發(fā)現(xiàn)消費(fèi)總額為1080元乏苦,singo的老婆很詫異,以為出 現(xiàn)了幻覺,幻讀就這樣產(chǎn)生了汇荐。

注:Mysql的默認(rèn)隔離級(jí)別就是Repeatable read洞就。

4、serializable

  • 事務(wù)A和事務(wù)B掀淘,事務(wù)A在操作數(shù)據(jù)庫時(shí)旬蟋,事務(wù)B只能排隊(duì)等待
  • 這種隔離級(jí)別很少使用,吞吐量太低革娄,用戶體驗(yàn)差
  • 這種級(jí)別可以避免“幻像讀”倾贰,每一次讀取的都是數(shù)據(jù)庫中真實(shí)存在數(shù)據(jù),事務(wù)A與事務(wù)B串行拦惋,而不并發(fā)

5匆浙、臟讀、不可重復(fù)讀厕妖、幻讀

1.臟讀:
臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù)首尼,并且對(duì)數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中言秸,這時(shí)软能,另外一個(gè)事務(wù)也訪問這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)井仰。


2.不可重復(fù)讀:
是指在一個(gè)事務(wù)內(nèi),多次讀同一數(shù)據(jù)破加。在這個(gè)事務(wù)還沒有結(jié)束時(shí)俱恶,另外一個(gè)事務(wù)也訪問該同一數(shù)據(jù)。那么范舀,在第一個(gè)事務(wù)中的兩次讀數(shù)據(jù)之間合是,由于第二個(gè)事務(wù)的修改,那么第一個(gè)事務(wù)兩次讀到的的數(shù)據(jù)可能是不一樣的锭环。這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的聪全,因此稱為是不可重復(fù)讀。(即不能讀到相同的數(shù)據(jù)內(nèi)容)
例如辅辩,一個(gè)編輯人員兩次讀取同一文檔难礼,但在兩次讀取之間,作者重寫了該文檔玫锋。當(dāng)編輯人員第二次讀取文檔時(shí)蛾茉,文檔已更改。原始讀取不可重復(fù)撩鹿。如果只有在作者全部完成編寫后編輯人員才可以讀取文檔谦炬,則可以避免該問題。


3.幻讀:
是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象,例如第一個(gè)事務(wù)對(duì)一個(gè)表中的數(shù)據(jù)進(jìn)行了修改键思,這種修改涉及到表中的全部數(shù)據(jù)行础爬。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù)吼鳞,這種修改是向表中插入一行新數(shù)據(jù)看蚜。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行赖条,就好象
發(fā)生了幻覺一樣失乾。
例如,一個(gè)編輯人員更改作者提交的文檔纬乍,但當(dāng)生產(chǎn)部門將其更改內(nèi)容合并到該文檔的主復(fù)本時(shí)碱茁,發(fā)現(xiàn)作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產(chǎn)部門完成對(duì)原始文檔的處理之前仿贬,任何人都不能將新材料添加到文檔中纽竣,則可以避免該問題。

十茧泪、隔離級(jí)別與一致性關(guān)系

十一蜓氨、設(shè)置事務(wù)隔離級(jí)別
方式一
可以在my.ini(windows)、my.cnf(linux)文件中使用transaction-isolation選項(xiàng)來設(shè)置服務(wù)器的缺省事務(wù)隔離級(jí)別队伟。

該選項(xiàng)值可以是:

– READ-UNCOMMITTED
– READ-COMMITTED
– REPEATABLE-READ
– SERIALIZABLE

? 例如:

[mysqld]
transaction-isolation = READ-COMMITTED

方式二
通過命令動(dòng)態(tài)設(shè)置隔離級(jí)別
? 隔離級(jí)別也可以在運(yùn)行的服務(wù)器中動(dòng)態(tài)設(shè)置穴吹,應(yīng)使用SET TRANSACTION ISOLATION LEVEL語句。
? 其語法模式為:

        SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL <isolation-level>
        其中的<isolation-level>可以是:
    –   READ UNCOMMITTED
    –   READ COMMITTED
    –   REPEATABLE READ
    –   SERIALIZABLE
    ?   例如: SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

十二嗜侮、隔離級(jí)別的作用范圍
? 事務(wù)隔離級(jí)別的作用范圍分為兩種:
– 全局級(jí):對(duì)所有的會(huì)話有效
– 會(huì)話級(jí):只對(duì)當(dāng)前的會(huì)話有效
? 例如港令,設(shè)置會(huì)話級(jí)隔離級(jí)別為READ COMMITTED :
mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
或:
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED锈颗;
? 設(shè)置全局級(jí)隔離級(jí)別為READ COMMITTED :
mysql> SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED顷霹;

十三、查看隔離級(jí)別

mysql中:
查看本連接的隔離級(jí)別:select  @@tx_isolation;
查看整體的隔離級(jí)別:select @@global.tx_isolation;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末击吱,一起剝皮案震驚了整個(gè)濱河市淋淀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌覆醇,老刑警劉巖朵纷,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異永脓,居然都是意外死亡柴罐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門憨奸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來革屠,“玉大人,你說我怎么就攤上這事∷浦ィ” “怎么了那婉?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)党瓮。 經(jīng)常有香客問我详炬,道長(zhǎng),這世上最難降的妖魔是什么寞奸? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任呛谜,我火速辦了婚禮,結(jié)果婚禮上枪萄,老公的妹妹穿的比我還像新娘隐岛。我一直安慰自己,他們只是感情好瓷翻,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布聚凹。 她就那樣靜靜地躺著,像睡著了一般齐帚。 火紅的嫁衣襯著肌膚如雪妒牙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天对妄,我揣著相機(jī)與錄音湘今,去河邊找鬼。 笑死剪菱,一個(gè)胖子當(dāng)著我的面吹牛摩瞎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琅豆,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼愉豺,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼篓吁!你這毒婦竟也來了茫因?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤杖剪,失蹤者是張志新(化名)和其女友劉穎冻押,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盛嘿,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洛巢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了次兆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稿茉。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出漓库,到底是詐尸還是另有隱情恃慧,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布渺蒿,位于F島的核電站痢士,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茂装。R本人自食惡果不足惜怠蹂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望少态。 院中可真熱鬧城侧,春花似錦、人聲如沸况增。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澳骤。三九已至歧强,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間为肮,已是汗流浹背摊册。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颊艳,地道東北人茅特。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像棋枕,于是被迫代替她去往敵國(guó)和親白修。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容