理解MySQL數(shù)據(jù)庫事務(wù)
1. 什么是事務(wù)處理?
事務(wù)處理是一種機(jī)制,它是用來管理必須成批執(zhí)行的mysql操作。來保證數(shù)據(jù)庫不完整的操作結(jié)果。
2. 為什么要使用事務(wù)處理?
在使用mysql操作數(shù)據(jù)的過程中,如果只是簡單的中小型程序而言,我們不需要考慮mysql的事務(wù)。但是在比較復(fù)雜的情況下,用戶執(zhí)行某些數(shù)據(jù)操作過程中,需要通過一組sql語句執(zhí)行多項并行任務(wù)的時候。就必須保證操作數(shù)據(jù)的同步性。并且在執(zhí)行中,產(chǎn)生依賴關(guān)系的動作能夠同時操作成功或同時返回初始狀態(tài)。那么在這種情況下,就需要考慮使用mysql事務(wù)處理了。
在mysql中,事務(wù)是由單獨(dú)的一個或多個sql語句組成的。每個sql語句都是互相依賴的。如果某條sql語句執(zhí)行失敗或發(fā)生異常的情況下,那么整個操作都會回滾。所有的數(shù)據(jù)操作都會返回原始的初始狀態(tài)。如果單元中的所有的sql執(zhí)行成功,那么事務(wù)就被順利執(zhí)行。
那么打個比方,比如銀行轉(zhuǎn)賬為列:
用戶A需要給用戶B轉(zhuǎn)賬1000元,那么用戶A使用手機(jī)直接把1000元打到用戶B的銀行卡中了,指令已經(jīng)發(fā)出去了,但是由于用戶A把用戶B的銀行卡號輸入錯了,那么這種情況下,用戶B的銀行卡是不會多出1000元了,但是用戶A銀行卡少了1000元,那這樣的話肯定是不合理的,因此我們需要將用戶A向用戶B轉(zhuǎn)賬這么一件事情當(dāng)做一個事務(wù)來處理。如果用戶B的真實(shí)姓名和銀行卡號對不上的話,那么整個轉(zhuǎn)賬事務(wù)就會失敗,那么因此需要使用回滾操作,回滾到轉(zhuǎn)賬前的初始狀態(tài)。因此用戶A也不會少1000元,用戶B也不會增加1000元。那么這種情況下才是最合理的。
事務(wù)處理中的一些術(shù)語的解釋:
事務(wù)(transaction)?指一組sql語句。
回退(rollback)?指撤銷指定sql語句的過程。
提交(commit)?指將未存儲的sql語句結(jié)果寫入到數(shù)據(jù)庫中。
保留點(diǎn)(savepoint)?指事務(wù)處理中設(shè)置的臨時占位符,我們可以對他們發(fā)布回退操作。
3. mysql存儲引擎
mysql的存儲引擎是可以改變的,默認(rèn)是 InnoDB 存儲引擎,mysql中有8種存儲引擎。
1. MyISAM:?他是高速引擎,但是不支持事務(wù)處理。
2. InnoDB:?支持行鎖定以及事務(wù)處理,速度比MyISAM稍慢
3. ISAM:?MyISAM的前身
4. MERGE:?將多個MyISAM類型的表作為一個表來處理的引擎
5. MEMORY,HEAP:?只在內(nèi)存上保存數(shù)據(jù)
6. Falcon:?一種新的存儲引擎,支持事務(wù)處理
7. ARCHIVE:?將數(shù)據(jù)壓縮后保存(只能支持INSERT/SELECT操作
8. CSV:?以CSV形式保存數(shù)據(jù)(應(yīng)用于跨平臺數(shù)據(jù)交換)
如上只是了解下有哪些存儲引擎,其實(shí)我們mysql的常見使用的存儲引擎就是 InnoDB,其他的我們可以簡單的了解下就
可以了。
數(shù)據(jù)庫事務(wù)相關(guān)命令如下:
1. 查看存儲引擎:SHOW CREATE TABLE 表名;
2. 更改引擎: ALTER TABLE 表名 ENGINE=新引擎名;
3. 回滾: ROLLBACK;
4. 聲明事務(wù)開始: BEIGIN;
5. 事務(wù)提交: COMMIT;
6. 查詢自動提交功能狀態(tài): SELECT @@AUTOCOMMIT;
7. 設(shè)置自動提交功能: SET AUTOCOMMIT=0或1;
8. 設(shè)置分離水平: SET SESSION TRANSACTION ISOLATION LEVEL 分離水平;
1. 查看存儲引擎,使用命令:SHOW CREATE TABLE 表名; 如下圖所示:

2. 更改存儲引擎,使用命令:ALTER TABLE 表名 ENGINE=新引擎名; 如下圖所示:

4. 事務(wù)處理
事務(wù)有如下四大特性:
1.?原子性:指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾。
2.?一致性:指事務(wù)必須使數(shù)據(jù)庫從一個一致性狀態(tài)變換到另一個一致性狀態(tài)。(比如拿轉(zhuǎn)賬來講,假設(shè)用戶A和用戶B兩者的錢加起來一共是2000,那么不管是用戶A還是用戶B之間如何轉(zhuǎn)賬,轉(zhuǎn)幾次賬,事務(wù)結(jié)束后兩個用戶的錢加起來應(yīng)該還是2000,所以這就是事務(wù)的一致性)。
3. 隔離性:指當(dāng)多個用戶并發(fā)訪問數(shù)據(jù)庫并且操作同一張表的時候,數(shù)據(jù)庫為每一個用戶開啟的事務(wù),不能被其他事務(wù)的操作所干擾,多個并發(fā)事務(wù)之間要相互隔離。
4. 持久性:指一個事務(wù)一旦被提交了,那么對數(shù)據(jù)庫中的數(shù)據(jù)的改變就是永久性的,哪怕是在數(shù)據(jù)庫系統(tǒng)遇到故障的情況下也不會丟失提交事務(wù)的操作。
如上就是事務(wù)四大特性。我們可以簡單的理解下就可以了。
4.1 回滾演示(ROLLBACK)
如下圖所示:

?
如上演示我們可以看到,當(dāng)我們刪除表格里面的數(shù)據(jù)的時候,我們再執(zhí)行回滾操作(ROLLBACK), 刪除的記錄又恢復(fù)到begin之前的狀態(tài),如果我們將 ROLLBACK 換成 COMMIT 的話,那么事務(wù)將會被提交了,刪除的事務(wù)就不能再恢復(fù)了。
如下繼續(xù)演示下:

4.2 自動提交
當(dāng)我們的mysql的數(shù)據(jù)庫的引擎為 InnoDB的時候,我們可以設(shè)置自動提交功能是否開啟,當(dāng)自動提交功能為on的時候,命令執(zhí)行就會提交(commit). 當(dāng)我們自動提交設(shè)置為off的時候,必須執(zhí)行commit才會提交事務(wù)。但是我們可以使用rollback進(jìn)行回滾操作。
首先我們來查詢下當(dāng)前自動提交功能的狀態(tài);如下基本語法:
select @@autocommit;
如下所示:

我們需要設(shè)置自動提交功能的基本語法如下:
set autocommit = 0 或 1;
注意:0 代表是off,1代表的是on.
4.2.1 自動提交設(shè)置為off
如果我們將自動提交設(shè)置為off的時候,我們插入一條記錄,然后我們使用回滾 rollback的操作,我們再次查看記錄,會發(fā)現(xiàn)我們返回到了初始狀態(tài)。如下圖所示:
但是當(dāng)我們將自動提交設(shè)置為on的時候,我們插入一條數(shù)據(jù)后,然后我們使用回滾 rollback的時候,我們再次查看記錄,會發(fā)現(xiàn)在我們插入數(shù)據(jù)的時候,會自動觸發(fā)commit狀態(tài)(自動提交). 因此回滾的時候是回滾不了初始咋提的。
如下圖所示:

4.3 部分回滾 savepoint
如果我們設(shè)置 autocommit = 0 的時候,不自動提交,然后我們使用 rollback會回滾到我們的初始狀態(tài)的時候,而我們現(xiàn)在通過 savepoint 就可以保存一個點(diǎn),通過 rollback to savepoint 就可以回滾到保存的點(diǎn)了。
部分回滾主要有兩個步驟:
1. 保存點(diǎn):執(zhí)行命令:savepoint 保存點(diǎn)名;
2. 回滾到保存點(diǎn):執(zhí)行命令:rollback to savepoint 保存點(diǎn)名;
比如如下所示:
4.4 鎖定與事務(wù)處理
如上我們使用rollback操作是指一個用戶下進(jìn)行的。但是如果是多個用戶下同時操作呢?比如說12306購票系統(tǒng),無數(shù)的人同時使用,因此我們的事務(wù)必須能夠處理多個用戶同時操作的情況。因此我們需要鎖定。
比如說:我們過年的時候會在12306網(wǎng)站上同一刻時間點(diǎn)買票,比如說用戶A和用戶B同時登陸購票網(wǎng)站,并且買的是同一張票,比如說看到的都是剩余1張票了,因此用戶A和用戶B趕緊下單,那么這個下單的時間點(diǎn)肯定是有先后順序?qū)Π桑敲醇偃缬脩鬉下單的時間更早,因此該票會被鎖定,因此用戶B就不能買了。這種情況就是事務(wù)的鎖定。
4.4.1 鎖定分為 共享鎖定 和 排他鎖定。
什么是共享鎖定呢?共享鎖定是將對象數(shù)據(jù)變?yōu)橹蛔x形式,不能進(jìn)行修改的。
什么是排他鎖定呢?排他鎖定就是當(dāng)我們執(zhí)行 insert/update/delete的時候,其他的事務(wù)不能讀取該數(shù)據(jù)。因此我們也可以叫做寫入鎖定。
4.4.2 事務(wù)處理的分離水平
事務(wù)處理的分離水平一般是 READ UNCOMMITED; 它可以是非提交讀取,也可以不可重復(fù)讀取,還可以是幻像讀取。
設(shè)置分離水平可以使用如下命令:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
1. 理解非提交讀取
什么是非提交讀取呢?指的是別的事務(wù)能夠讀取到還沒有提交的更新數(shù)據(jù)。什么意思呢?比如說我使用sql語句更新了一些數(shù)據(jù),但是并沒有使用commit提交,但是其他的用戶可以查詢到我剛剛更新的數(shù)據(jù)。為了演示下,我們可以打開2個命令行窗口,演示如下:

2. 理解不可重復(fù)讀取
不可重復(fù)讀取是指在某事務(wù)處理過程中對數(shù)據(jù)進(jìn)行讀取,由于該事務(wù)更新操作導(dǎo)致多次讀取數(shù)據(jù)時發(fā)生了改變。這個demo先省略了。。。
3. 理解幻象讀取
幻象讀取指的是,在某事物處理數(shù)據(jù)過程中對數(shù)據(jù)多次讀取,由于該事務(wù)的插入/刪除操作而導(dǎo)致在多次讀取過程中讀取到不存在或者消失的數(shù)據(jù)。這個demo先省略了。。。
