1. 程式人生 > >事務處理是將多個操作或者命令一起執行,所有命令全

事務處理是將多個操作或者命令一起執行,所有命令全

事務處理用於有效記錄某機構感興趣的業務活動(稱為事務)的資料處理(例如銷售、供貨的定購或貨幣傳輸)。通常,聯機事務處理 (OLTP) 系統執行大量的相對較小的事務。——百度百科

事務處理是將多個操作或者命令一起執行,所有命令全部成功執行才意味著該事務的成功,任何一個命令失敗都意味著該事務的失敗。

以銀行轉賬為例(100塊都不給),
A要給B 轉賬100元,
A轉賬的指令已經成功發出,而B 由於未知的原因接收失敗,
如果兩個命令單獨執行,那麼A賬戶少了100塊,但是B又沒收到100塊,顯而易見是不合理的;
如果將A向B 轉賬100元當成一個事務處理,那麼由於B 接收的失敗,整個轉賬事務都將失敗,A不會少100,B更不會增加100,這個時候“100塊都不給”才是合理的情況。
事務處理

因此,事務處理是不是一榮俱榮,而是一毀全毀。

接下來介紹MySQL資料庫中如何進行事務處理以及鎖定。

0 資料庫事務處理相關命令

進行的操作 命令
檢視儲存引擎 SHOW CREATE TABLE 表名;
更改引擎 ALTER TABLE 表名 ENGINE=新引擎名;
回滾 ROLLBACK;
宣告事務開始 BEIGIN;
事務提交 COMMIT;
查詢自動提交功能狀態 SELECT @@AUTOCOMMIT;
設定自動提交功能 SET AUTOCOMMIT=0或1;
設定分離水平 SET SESSION TRANSACTION ISOLATION LEVEL 分離水平;

1 儲存引擎

MySQL資料庫的儲存引擎是可以選擇改變和替換的(可替換儲存引擎構架,Pluggable Storage Engine Architecture)。MySQL主要有8種儲存引擎:

儲存引擎 特徵
MyISAM 高速引擎,不支援事務處理
InnoDB 支援行鎖定以及事務處理,速度比MyISAM稍慢
ISAM MyISAM的前身
MERGE 將多個MyISAM型別的表作為一個表來處理的引擎
MEMORY,HEAP 只在記憶體上儲存資料
Falcon 一種新的儲存引擎,支援事務處理
ARCHIVE 將資料壓縮後儲存(只能支援INSERT/SELECT操作
CSV 以CSV形式儲存資料(應用於跨平臺資料交換)

MySQL的儲存引擎種類和特徵

(1)檢視儲存引擎 SHOW CREATE TABLE 表名;
檢視某表使用的儲存引擎,語法程式碼如下:

 `SHOW CREATE TABLE 表名;`
  
  • 1

如,要查看錶customer的儲存引擎,可以輸入程式碼:

 `SHOW CREATE TABLE customer;`
  
  • 1

檢視儲存引擎
如圖表所示ENGINE=後面顯示的就是儲存引擎。

(2)更改儲存引擎ALTER TABLE 表名 ENGINE=新引擎名;

若要更改儲存引擎,可以使用程式碼:

>ALTER TABLE 表名 ENGINE=新引擎名;
  
  • 1

eg:將表customer的儲存引擎修改為MyISAM,輸入指令:

ALTER TABLE customer ENGINE=MyISAM;
  
  • 1

更改儲存引擎

2 事務處理

之前講到,事務處理是一毀全毀,因此事務中任意一個任務或指令失敗,整個事務都將失敗。那是怎麼實現的呢?方法是時間中多個任務全部成功,則任務成功結束,並且會進行提交(COMMIT),如果任何一件任務失敗,則強制回滾(ROLLBACK)到初始狀態。

事務處理涉及到三個最重要的命令:BEGIN,ROLLBACK,COMMIT,分別表示宣告事務開始,回滾和確認提交。

(1)回滾演示(ROLLBACK)
首先將表格customer 的儲存引擎設定為InnoDB,
確認表格資料;SELECT * FROM customer;
事務開始;BEGIN;
刪除表格資料;DELETE FROM customer;
再次查看錶格資料;SELECT * FROM customer;
回滾到初始狀態;ROLLBACK;
再次查看錶格資料;SELECT * FROM customer;

回滾
可以看到,當執行ROLLBACK;之後,刪除的記錄又恢復到了BEGIN之前的狀態,如果將ROLLBACK 換成COMMIT,那麼事務將會提交,刪除的記錄就不能恢復了。

(2)自動提交

當搜尋引擎為MyISAM時,因為不支援事務處理,因此命令一旦執行,就一定會提交,這種預設的提交方式被稱為自動提交

而當搜尋引擎設定為InnoDB時,可以設定自動提交功能是否開啟,當自動提交功能為ON時,命令執行就會提交(COMMIT),而自動提交設定為OFF 時,必須執行COMMIT才提交,可以使用ROLLBACK進行回滾。

查詢當前自動提交功能狀態:

>SELECT @@AUTOCOMMIT;
  
  • 1

設定自動提交功能:

>SET AUTOCOMMIT=0或1;
  
  • 1

如圖,將自動提交設定為OFF,插入一條記錄,然後使用回滾ROLLBACK,再次檢視記錄,會發現不見了。
自動提交

(3)部分回滾 SAVEPOINT

直接ROLLBACK會回滾到BEGIN開始之前的地方,而通過SAVEPOINT可以儲存一個點,通過ROLLBACK TO SAVEPOINT就可以回滾到儲存點了,也就實現了“想去哪就去了哪”。
部分回滾

部分回滾主要有兩個步驟:
①儲存點

>SAVEPOINT 儲存點名;
  
  • 1

②回滾到儲存點

>ROLLBACK TO SAVEPOINT 儲存點名;
  
  • 1

eg:
mysql部分回滾

(4)不能事務處理的命令(直接提交)
大部分命令都可以通過事務處理(BEGIN -ROLLBACK- COMMIT)進行操作,但是:

  • DROP DATABASE;
  • DROP TABLE;
  • DROP;
  • ALTER TABLE

不能通過事務處理,會直接COMMIT;

3 鎖定與事務處理

前面講到的ROLLBACK 等操作指令都是基於一個使用者進行的。但是事務型別往往不只一個使用者,多個使用者同時操作,如被人廣泛詬病的“12306”火車票購票系統,全國各地的售票視窗以及網際網路購票註冊賬戶,成千上萬的使用者同時使用,因此事務處理必須能夠處理多個使用者同時操作的情況,這就需要鎖定。

舉個例子,如果某班火車只剩最後一張票,A和B 同時登陸網站購票,得到的反饋是還剩一張,於是A,B 都趕緊下單,處理這種衝突事件,就需要對該事務進行鎖定(LOCK),接觸鎖定被稱為解鎖(Unlock)

鎖定

3.1 鎖定

(1)鎖定的分類

鎖定分為共享鎖定(Shared Lock)和排他鎖定(Exclusive Lock):

  • 共享鎖定是將物件資料變為只讀形式,不能進行更新,所以也成為讀取鎖定;
  • 排他鎖定是當執行INSERT/UPDATE/DELETE的時候,其它事務不能讀取該資料,因此也成為寫入鎖定。

(2)鎖定的粒度

鎖定物件的大小是鎖定的粒度,有三種粒度:

  • 記錄
  • 資料庫

3.2 事務處理的分離水平

需要使用鎖定來有效解決事務衝突的情況,但是鎖定也會使效能下降(因為別人無法訪問),因此頻繁鎖定不一定合理,資料庫中,使用分離水平來表示事務處理之間的影響程度。

事務處理的分離水平對應的資料整合情況:

分離水平 非提交讀取 不可重複讀取 幻象讀取
READ UNCOMMITED
READ COMMITED ×
REPEATABLE READ × ×
SERIALIZABLE × × ×

設定分離水平可以使用命令:

>SET SESSION TRANSACTION ISOLATION LEVEL 分離水平;
  
  • 1


為了模擬多個使用者對資料庫進行訪問和操作,我們開啟兩個命令視窗接入MySQL。
(1)非提交讀取

非提交讀取指的是別的事務能夠讀取到還沒有提交的更新資料,只發生在分離水平為READ UNCOMMITED的情況下。

因為對事務處理的讀取沒有任何限制,所以一般不推薦使用。

eg:
非提交讀取

兩個視窗的執行順序如圖紅色序號所示:
①首先再A視窗對Id為g001的記錄的nam進行修改;
②然後B進行訪問,發現已經能夠讀取新的nam;
③A執行ROLLBACK,回滾到初始狀態(nam恢復原來的記錄);
④B再次查詢,又得到OLD記錄(舊記錄);
⑤A再次UPDATE,並COMMIT;
⑥B再次SELECT,得到新紀錄(new)。
可以看到,當A還沒提交,B就可以看到更新的資料,這個時候很可能出現問題,比如A後來執行ROLLBACK,B看到的資料實際上是錯誤的資料。

(2)不可重複讀取

不可重複讀取是指在某事務處理過程中對資料進行讀取,由於該事務更新操作導致多次讀取資料時發生了改變。

不可重複讀取發生在READ COMMITED 一下的分離水平。

eg:
不可重複讀取
命令順序依然如圖紅色數字所示:
①A更新id為g001的nam;
②B查詢,結果是OLD資料;
③A提交更新;
④B再次查詢,得到更新後的NEW資料。
B先後兩次查詢,結果不一致。

(3)幻象讀取

幻象讀取指的是,在某事物處理資料過程中對資料多次讀取,由於該事務的插入/刪除操作而導致在多次讀取過程中讀取到不存在或者消失的資料。

下圖是幻象讀取發生的例子:

幻象讀取發生
①A事務開始;
②B查詢;
③A插入一條記錄並提交;
④B再次查詢;
可以看到B連續執行兩次的查詢,前後結果不一致。

當設定分離水平為SERIALIZABLE時,可以消除幻象讀取。

消除幻象讀取
①A事務開始;
②B查詢;
③A插入一條資料;(此時A會一直等待,直到B提交)
④B提交;
⑤A提交;
⑥B再次查詢;

特別需要注意的是,由於B正在讀取資料,當A 執行插入命令時,無法立馬得到結果,而是一直等待,直到B提交。當B提交時,A的插入命令自動完成。

3.3 死鎖 Dead Lock(狹路相逢勇者勝)

死鎖指的是兩個事務互相對待對方釋放鎖定,則永遠也不可能接觸鎖定的狀態。

如A,B兩個使用者都對錶customer中記錄’g001’和’g002’實施了排他鎖定,由於兩個事務互相等待對方釋放鎖定,所以形成了死鎖。
死鎖
A和B執行命令順序紅色字型所示:
①A事務開始,並對’g001’進行了更新;
②B事務開始,並對’g002’進行了更新;
③A對’g002’進行更新;(A等待B提交釋放鎖定)
④B對’g001’進行更新;(B等待A提交釋放鎖定,A、B互相等待陷入死鎖)

此時,MySQL資料庫讓B強制解除鎖定,A繼續執行;

⑤A提交;
⑥B回滾並查詢,得到A事務更新的資料;

事務處理用於有效記錄某機構感興趣的業務活動(稱為事務)的資料處理(例如銷售、供貨的定購或貨幣傳輸)。通常,聯機事務處理 (OLTP) 系統執行大量的相對較小的事務。——百度百科