1. 什么是事務處理?
事務處理是一種機制,它是用來管理必須成批執行的mysql操作。來保證數據庫不完整的操作結果。
2. 為什么要使用事務處理?
在使用mysql操作數據的過程中,如果只是簡單的中小型程序而言,我們不需要考慮mysql的事務。但是在比較復雜的情況下,用戶執行某些數據操作過程中,需要通過一組sql語句執行多項並行任務的時候。就必須保證操作數據的同步性。並且在執行中,產生依賴關系的動作能夠同時操作成功或同時返回初始狀態。那么在這種情況下,就需要考慮使用mysql事務處理了。
在mysql中,事務是由單獨的一個或多個sql語句組成的。每個sql語句都是互相依賴的。如果某條sql語句執行失敗或發生異常的情況下,那么整個操作都會回滾。所有的數據操作都會返回原始的初始狀態。如果單元中的所有的sql執行成功,那么事務就被順利執行。
那么打個比方,比如銀行轉賬為列:
用戶A需要給用戶B轉賬1000元,那么用戶A使用手機直接把1000元打到用戶B的銀行卡中了,指令已經發出去了,但是由於用戶A把用戶B的銀行卡號輸入錯了,那么這種情況下,用戶B的銀行卡是不會多出1000元了,但是用戶A銀行卡少了1000元,那這樣的話肯定是不合理的,因此我們需要將用戶A向用戶B轉賬這么一件事情當做一個事務來處理。如果用戶B的真實姓名和銀行卡號對不上的話,那么整個轉賬事務就會失敗,那么因此需要使用回滾操作,回滾到轉賬前的初始狀態。因此用戶A也不會少1000元,用戶B也不會增加1000元。那么這種情況下才是最合理的。
事務處理中的一些術語的解釋:
事務(transaction) 指一組sql語句。
回退(rollback) 指撤銷指定sql語句的過程。
提交(commit) 指將未存儲的sql語句結果寫入到數據庫中。
保留點(savepoint) 指事務處理中設置的臨時占位符,我們可以對他們發布回退操作。
3. mysql存儲引擎
mysql的存儲引擎是可以改變的,默認是 InnoDB 存儲引擎,mysql中有8種存儲引擎。
1. MyISAM: 他是高速引擎,但是不支持事務處理。
2. InnoDB: 支持行鎖定以及事務處理,速度比MyISAM稍慢
3. ISAM: MyISAM的前身
4. MERGE: 將多個MyISAM類型的表作為一個表來處理的引擎
5. MEMORY,HEAP: 只在內存上保存數據
6. Falcon: 一種新的存儲引擎,支持事務處理
7. ARCHIVE: 將數據壓縮后保存(只能支持INSERT/SELECT操作
8. CSV: 以CSV形式保存數據(應用於跨平台數據交換)
如上只是了解下有哪些存儲引擎,其實我們mysql的常見使用的存儲引擎就是 InnoDB,其他的我們可以簡單的了解下就
可以了。
數據庫事務相關命令如下:
1. 查看存儲引擎:SHOW CREATE TABLE 表名;
2. 更改引擎: ALTER TABLE 表名 ENGINE=新引擎名;
3. 回滾: ROLLBACK;
4. 聲明事務開始: BEIGIN;
5. 事務提交: COMMIT;
6. 查詢自動提交功能狀態: SELECT @@AUTOCOMMIT;
7. 設置自動提交功能: SET AUTOCOMMIT=0或1;
8. 設置分離水平: SET SESSION TRANSACTION ISOLATION LEVEL 分離水平;
1. 查看存儲引擎,使用命令:SHOW CREATE TABLE 表名; 如下圖所示:
2. 更改存儲引擎,使用命令:ALTER TABLE 表名 ENGINE=新引擎名; 如下圖所示:
4. 事務處理
事務有如下四大特性:
1. 原子性:指事務包含的所有操作要么全部成功,要么全部失敗回滾。
2. 一致性:指事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態。(比如拿轉賬來講,假設用戶A和用戶B兩者的錢加起來一共是2000,那么不管是用戶A還是用戶B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢加起來應該還是2000,所以這就是事務的一致性)。
3. 隔離性:指當多個用戶並發訪問數據庫並且操作同一張表的時候,數據庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個並發事務之間要相互隔離。
4. 持久性:指一個事務一旦被提交了,那么對數據庫中的數據的改變就是永久性的,哪怕是在數據庫系統遇到故障的情況下也不會丟失提交事務的操作。
如上就是事務四大特性。我們可以簡單的理解下就可以了。
4.1 回滾演示(ROLLBACK)
如下圖所示:
如上演示我們可以看到,當我們刪除表格里面的數據的時候,我們再執行回滾操作(ROLLBACK), 刪除的記錄又恢復到begin之前的狀態,如果我們將 ROLLBACK 換成 COMMIT 的話,那么事務將會被提交了,刪除的事務就不能再恢復了。
如下繼續演示下:
4.2 自動提交
當我們的mysql的數據庫的引擎為 InnoDB的時候,我們可以設置自動提交功能是否開啟,當自動提交功能為on的時候,命令執行就會提交(commit). 當我們自動提交設置為off的時候,必須執行commit才會提交事務。但是我們可以使用rollback進行回滾操作。
首先我們來查詢下當前自動提交功能的狀態;如下基本語法:
select @@autocommit;
如下所示:
我們需要設置自動提交功能的基本語法如下:
set autocommit = 0 或 1;
注意:0 代表是off,1代表的是on.
4.2.1 自動提交設置為off
如果我們將自動提交設置為off的時候,我們插入一條記錄,然后我們使用回滾 rollback的操作,我們再次查看記錄,會發現我們返回到了初始狀態。如下圖所示:
但是當我們將自動提交設置為on的時候,我們插入一條數據后,然后我們使用回滾 rollback的時候,我們再次查看記錄,會發現在我們插入數據的時候,會自動觸發commit狀態(自動提交). 因此回滾的時候是回滾不了初始咋提的。
如下圖所示:
4.3 部分回滾 savepoint
如果我們設置 autocommit = 0 的時候,不自動提交,然后我們使用 rollback會回滾到我們的初始狀態的時候,而我們現在通過 savepoint 就可以保存一個點,通過 rollback to savepoint 就可以回滾到保存的點了。
部分回滾主要有兩個步驟:
1. 保存點:執行命令:savepoint 保存點名;
2. 回滾到保存點:執行命令:rollback to savepoint 保存點名;
比如如下所示:
4.4 鎖定與事務處理
如上我們使用rollback操作是指一個用戶下進行的。但是如果是多個用戶下同時操作呢?比如說12306購票系統,無數的人同時使用,因此我們的事務必須能夠處理多個用戶同時操作的情況。因此我們需要鎖定。
比如說:我們過年的時候會在12306網站上同一刻時間點買票,比如說用戶A和用戶B同時登陸購票網站,並且買的是同一張票,比如說看到的都是剩余1張票了,因此用戶A和用戶B趕緊下單,那么這個下單的時間點肯定是有先后順序對吧,那么假如用戶A下單的時間更早,因此該票會被鎖定,因此用戶B就不能買了。這種情況就是事務的鎖定。
4.4.1 鎖定分為 共享鎖定 和 排他鎖定。
什么是共享鎖定呢?共享鎖定是將對象數據變為只讀形式,不能進行修改的。
什么是排他鎖定呢?排他鎖定就是當我們執行 insert/update/delete的時候,其他的事務不能讀取該數據。因此我們也可以叫做寫入鎖定。
4.4.2 事務處理的分離水平
事務處理的分離水平一般是 READ UNCOMMITED; 它可以是非提交讀取,也可以不可重復讀取,還可以是幻像讀取。
設置分離水平可以使用如下命令:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
1. 理解非提交讀取
什么是非提交讀取呢?指的是別的事務能夠讀取到還沒有提交的更新數據。什么意思呢?比如說我使用sql語句更新了一些數據,但是並沒有使用commit提交,但是其他的用戶可以查詢到我剛剛更新的數據。為了演示下,我們可以打開2個命令行窗口,演示如下:
2. 理解不可重復讀取
不可重復讀取是指在某事務處理過程中對數據進行讀取,由於該事務更新操作導致多次讀取數據時發生了改變。這個demo先省略了。。。
3. 理解幻象讀取
幻象讀取指的是,在某事物處理數據過程中對數據多次讀取,由於該事務的插入/刪除操作而導致在多次讀取過程中讀取到不存在或者消失的數據。這個demo先省略了。。。