MySQL實戰11 事務控制

MySQL實戰 目錄

前言

TCL:Transaction Control Language,事務控制語言

事務:在MySQL數據庫中表示一條或多條Sql語句組合在一起的一個執行單元。
這個執行單元要么全部執行,要么全部不執行,否則就會出現邏輯錯誤!

比如銀行里的轉賬這個事情:
A賬號余額:1000
B賬號余額:1000
現在A轉500元給B,那么完成這個轉賬的事務,數據中的SQL應該是這樣的執行過程:
步驟1:A賬號上要減少500元
update 儲蓄表 set A.余額=A.余額-500 where 賬號名='A';
步驟2:B賬號上要增加500元
update 儲蓄表 set B.余額=B.余額+500 where 賬號名='B';

如果沒有事務處理這個功能,上面的情況下,很可能會發生這樣的情況:
步驟1執行成功 A的余額變為:500
剛開始執行步驟2的時候,突然出現某系統錯誤,導致步驟2執行失敗!
步驟1成功 步驟2失敗:A的錢減少了,B的錢沒增加!

所以在類似的場景需求中我們需要事務處理:實現將步驟1和步驟2的SQL語句綁定在一起,要么都執行成功,要么不管是步驟1執行出錯還是2出錯,數據庫里的數據狀態會回滾到沒有執行任何步驟1或2的SQL語句之前!

1.MySQL數據中的存儲引擎

在具體講事務之前,還是說說MySQL數據中的存儲引擎:innoDB
1.什么是存儲引擎:在mysql中的數據使用各種不同的技術來存儲在磁盤文件(或內存)
當中的,這種具體的存儲技術就是我們說的存儲引擎。
2.我們可以通過show engines;命令來查看mysql支持的存儲引擎。
3.在mysql可以選擇的這些存儲引擎中,innodb,myisam,memory這三個是最常用的,但其中只有innodb支持事務處理,而其他是不支持事務處理的。

2.事務的ACID特點:

  1. 原子性(Atomicity): 組成事務的SQL語句不可再分,要么都執行,要么都不執行。
  2. 一致性(Consistency): 事務必須讓數據的數據狀態變化到另一個一致性的狀態,比如:
    剛剛的例子中A和B的余額總和是2000,轉賬后,A和B的余額總和不能變。前后具有一致性。
  3. 隔離性(Isolation): 一個事務的執行,不受其他事務的干擾,相互應該是隔離的,但是實際上是很難做到的,要通過隔離級別做選擇!
  4. 持久性(Durability): 一個事務被提交,并成功執行,那么它對數據的修改就是永久性的,接下來的其他操作或出現的故障,不能影響到它執行的結果!

3.MySQL的事務的創建:

1.隱視事務:事務沒有明顯的開始和結束的標記,這時候像insert語句,update語句和delete語句,每一條SQL語句就默認是一個事務。

顯然,隱視事務在類似轉賬的邏輯業務需求的時候,就無法處理了!

2.顯示事務:說白了,這個事務模式,就要我們的中程序手動的用命令來開啟事務,和結束事務,并讓事務里的多余SQL語句去執行。

注意:默認MySQL是開啟自動提交事務的,用show variables like ‘autocommit’;命令可以查看到。所以,開啟顯示事務前,需要 關掉它,用set autocommit=0;只對本身回話有效。

Show ENGINES;

show VARIABLES like 'autocommit';

#@1.開始事務
SET autocommit = 0;
show VARIABLES like 'autocommit';

START TRANSACTION;#可選的,執行set autocommit=0已經默認開啟了!

#@2編寫事務中的SQL語句(主要是:SELECT UPDATE DELETE INSERT等語句)
  語句1;語句;.......
#@3結束事務
END
    commit;  :提交事務去真正執行 # 或者 rollback;  :回滾事務,恢復數據庫執行前等狀態!
    
示例:
DROP TABLE IF EXISTS account;

CREATE TABLE account(
  id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20),
    balance DOUBLE
);

INSERT INTO account(username,balance ) VALUES('A',1000),('B',1000);
    
    START TRANSACTION;
   #實現A賬號轉帳500元到B賬號
     UPDATE account SET balance = 500 WHERE username = 'A';
     UPDATE account SET balance = 1500 WHERE username = 'B';
     ROLLBACK; #事務回滾

     SELECT * FROM account;
        START TRANSACTION;
   #實現A賬號轉帳500元到B賬號
     UPDATE account SET balance = 500 WHERE username = 'A';
     UPDATE account SET balance = 1500 WHERE username = 'B';
     COMMIT; #事務執行

     SELECT * FROM account;

4.運行多事務導致多并發問題

同時運行的多個事務, 當這些事務訪問數據庫中相同的數據時, 如果沒有采取必要的隔離機制,就會導致各種并發問題 , 比如

4.1 臟讀(沒有被提交的操作)

對于兩個事務 T1,T2, T1 讀取了已經被 T2 更新但還沒有被提交的字段之后, 若T2 回滾, T1讀取的內容就是臨時且無效的。T1:張飛女朋友轉500元給張飛,但是沒有提交事務T1T2:張飛看賬戶余額500元(開心壞了)然后女朋友撤銷500元轉賬操作(T1回滾),那么張飛看到的500元是臨時無效的數據,是臟讀的數據。

4.2 不可重復讀(在臟讀基礎之上,更新update操作)

對于兩個事務T1, T2, T1讀取了一個字段, 然后T2更新了該字段之后, T1再次讀取同一個字段, 值就不同了。張飛第一次讀賬戶余額500元張飛第二次讀賬戶余額0元

4.3 幻讀(插入insert/刪除delete)

對于兩個事務T1, T2, T1 從一個表中讀取了一個字段, 然后T2在該表中插入了一些新的行之后, 如果T1 再次讀取同一個表, 就會多出幾行。張飛:請班級班上同學吃飯(班上就兩位同學)然后在沒有請客之前,班上有來了一位同學(由原來的請兩位同學吃飯、變成請三位同學吃飯,感覺出現了幻覺)

5.隔離級別

數據庫事務的隔離性: 數據庫系統必須具有隔離并發運行各個事務的能力,使它們不會相互影響, 避免各種并發問題。

當數據庫系統采用read Commited隔離級別時,會導致不可重復讀喝第二類丟失更新的并發問題,可以在應用程序中采用悲觀鎖或樂觀鎖來避免這類問題。從應用程序的角度,鎖可以分為以下幾類:
Serializable(串行化):一個事務在執行過程中完全看不到其他事務對數據庫所做的更新。
Repeatable Read(可重復讀):一個事務在執行過程中可以看到其他事務已經提交的新插入的記錄,但是不能看到其他事務對已有記錄的更新。
Read Commited(讀已提交數據):一個事務在執行過程中可以看到其他事務已經提交的新插入的記錄,而且能看到其他事務已經提交的對已有記錄的更新
Read Uncomitted(讀未提交數據):一個事務在執行過程中可以拷打其他事務沒有提交的新插入的記錄,而且能看到其他事務沒有提交的對已有記錄的更新。

隔離級別越高,越能保證數據的完整性和一致性,但是對并發性能的影響也越大。對于多數應用程序,可以有優先考慮把數據庫系統的隔離級別設為Read Commited,它能夠避免臟讀,而且具有較好的并發性能。盡管它會導致不可重復讀、虛讀和第二類丟失更新這些并發問題,在可能出現這類問題的個別場合,可以由應用程序采用悲觀鎖或樂觀鎖來控制。

當數據庫系統采用read Commited隔離級別時,會導致不可重復讀喝第二類丟失更新的并發問題,可以在應用程序中采用悲觀鎖或樂觀鎖來避免這類問題。從應用程序的角度,鎖可以分為以下幾類:

A.悲觀鎖:指在應用程序中顯示的為數據資源加鎖。盡管能防止丟失更新和不可重復讀這類并發問題,但是它會影響并發性能,因此應該謹慎地使用。

B.樂觀鎖:樂觀鎖假定當前事務操作數據資源時,不回有其他事務同時訪問該數據資源,因此完全依靠數據庫的隔離級別來自動管理鎖的工作。應用程序采用版本控制手段來避免可能出現的并發問題。

5.保存點(SAVEPOINT) 回滾

我們可以在MySQL處理過程中定義保存點(SAVEPOINT),然后回滾到指定的保存點前的狀態。

定義保存點,以及回滾到指定保存點前狀態的語法如下。

  1. 定義保存點---SAVEPOINT 保存點名;
  2. 回滾到指定保存點---ROLLBACK TO SAVEPOINT 保存點名:

下面演示將向表user中連續插入3條數據,在插入第2條數據的后面定義一個保存點,最后看看能否回滾到此保存點。

1.查看user表中的數據
     SELECT * from account;
2.MySQL事務開始
     BEGIN;
3.向表user中插入2條數據
    INSERT INTO account(username,balance ) VALUES('C',1000),('D',1000);
    SELECT * from account;
4.指定保存點,保存點名為test
     SAVEPOINT test;
5.向表user中插入1條數據
     INSERT INTO account(username,balance ) VALUES('E',1000);
     SELECT * from account;
6.回滾到保存點test
     ROLLBACK TO SAVEPOINT test;
     SELECT * from account;
我們可以看到保存點test以后插入的記錄沒有顯示了,即成功團滾到了定義保存點test前的狀態。利用保存點可以實現只提交事務中部分處理的功能。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,565評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,115評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,577評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,514評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,234評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,621評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,641評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,822評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,380評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,128評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,319評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,879評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,548評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,970評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,229評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,048評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,285評論 2 376

推薦閱讀更多精彩內容