參考見:https://zhidao.baidu.com/question/329349963.html
參考見:http://www.voidcn.com/article/p-cyrpkvrk-tx.html
參考見:https://blog.csdn.net/nanaranran/article/details/77716377
參考見:https://www.cnblogs.com/diegodu/p/8818776.html
6.1 事務
1.事務:是使用者定義的一個資料庫操作序列,這些操作要麼全做,要麼全不做,是一個不可分割的工作單位。
2.事務的劃分:1)顯式劃分事務;2)隱式劃分事務
3.事務的ACID特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持續性(Durability)
1)原子性:事務是 資料庫的邏輯工作單位,是不可分割的工作單元。事務中包括的諸操作要麼都做,要麼都不做。
2)一致性:事務執行的結果必須是使資料庫從一個一致性狀態轉向為另一個一致性狀態。一致性狀態是指資料庫中只包含成功事務提交的結果;不一致狀態是指資料庫中包含事務提交的部分結果。
3)隔離性:一個事務的執行不能被其他事務干擾,即一個事務內部的操作以及使用的資料對其他併發事務是隔離的,併發執行的各個事務之間不能互相干擾。
4)持續性:持續性也稱為永久性,是指一個事務一旦提交,它對資料庫中資料的改變就應該是永久性的,接下來的操作或故障不應該對其執行結果有任何的影響
4.Mysql中的事務控制:
1)mysql中的InnoDB
儲存引擎是innodb。nnodb是Mysql上第一個提供外來鍵約束的資料引擎,除了提供事務處理外,InnoDB還支援行鎖,提供和Oracle一樣的一致性的不加鎖讀取,能增加併發讀的使用者數量並提高效能,不會增加鎖的數量。InnoDB的設計目標是處理大容量資料時最大化效能,它的CPU利用率是其他所有基於磁碟的關聯式資料庫引擎中最有效的
InnoDB是一套放在Mysql後臺的完整的資料庫系統,InnoDB有自己的緩衝池能緩衝資料和索引,InnoDB還把資料和索引存放在表空間中,可能包含好幾個檔案,這和MyISAM表完全不同,在MyISAM中,表被存放在單獨的檔案中,InnoDB表的大小隻受限於作業系統檔案的大小,一般為2GB。
2)引數之autocommit
A:autocommit是mysql中InnoDB資料表中特有的語句。(只有在表引擎=InnoDB時,autocommit才會生效)並且,在InnoDB表中,所有的資料都是需要commit之後,才會在真實資料庫中生效
A:在沒有開啟事務(begin;)的InnoDB表中,autocommit才會生效。對已經開啟了事務的SQL語句,autocommit引數不會生效
eg:
InnoDB資料庫引擎:
update tablenam set id=999 where id=1;(快取生效)
commit;(真實生效)
其他資料庫引擎:
update tablenam set id=999 where id=1;(真實生效)
A:檢視autocommit:select @@autocommit
修改autocommit:set autocommit=0;(預設是1)
3)引數之completion_type
commit和commit work的級別一致,都用來提交事務(rollback和rollback work跟commit和commit work的關係一樣)不同之處在於commit work用來控制事務結束後的行為是chain還是release的。如果是chain,那麼就變成了鏈事務。
使用者可以通過引數completion_type來控制。預設為0,表示沒有任何操作,此時commit=commit work
當引數completion_type的值為1時,commit work等同於commit and chain,表示馬上自動開啟一個相同隔離級別的事務。
當引數completion_type的值為2時,commit work等同於commit and release,表示當事務提交後自動斷開與伺服器的連線。
4)樣例1:
mysql> set names utf8; Query OK, 0 rows affected (0.00 sec) mysql> create table t(a int, primary key (a))engine=innodb; Query OK, 0 rows affected (0.29 sec) mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 1 | +--------------+ 1 row in set (0.00 sec) mysql> set @@completion_type=1; Query OK, 0 rows affected (0.00 sec) mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> insert into t select 1; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> commit work; Query OK, 0 rows affected (0.00 sec) mysql> insert into t select 2; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> insert into t select 2; ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' mysql> rollback; Query OK, 0 rows affected (0.00 sec) # 回滾之後只有1這個記錄,而沒有2這個記錄 mysql> select * from t; +---+ | a | +---+ | 1 | +---+ 1 row in set (0.00 sec)
說明:在此樣例中,將completion_type設定成1,第一次通過commit work來insert這條記錄。之後insert 2的時候並沒有啟用begin(start transaction)來開啟一個事務,之後再插入一條重複的記錄2,這時會丟擲異常rollback後,最後發現只有1這樣的一條記錄。2並沒有被insert進去。因為completion_type為1的時候,commit work會開啟另外一個事務,因此2個insert語句是在同一個事務裡面的所以回滾以後沒有insert進去
5)樣例2:
mysql> set @@completion_type=2; Query OK, 0 rows affected (0.00 sec) mysql> begin -> ; Query OK, 0 rows affected (0.00 sec) mysql> insert into t select 3; Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> commit work; Query OK, 0 rows affected (0.00 sec) mysql> select @@versison; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 205656 Current database: test ERROR 1193 (HY000): Unknown system variable 'versison' mysql>
說明:引數completion_type為2時,commit work等同於commit and release,當事務提交的時候會自動斷開與db的連線
6)rollback(rollback work)
savepoint identifier:在事務中建立一個儲存點,一個事務允許有多個保護點
release savepoint identifier:刪除事務中的儲存點,當時一個儲存點也沒有執行這個命令,會報錯丟擲一個異常
說明:構成事務的每條語句都會commit,否則事務的每條語句都會rollback,這種保護還會涉及到單調的語句,一條語句要麼完成成功要麼完全回滾。但是一條語句失敗並不會導致前一條執行的語句西東回滾,他們的工作會保留,需要你手動commit或者rollback
5.事務的執行方式
兩種方式:序列/交叉併發執行
6.2 併發控制
1.丟失修改:兩個事務讀取統一資料並分別進行修改,T1先提交了修改結果,T2後提交的修改結果覆蓋了T1提交的結果,導致T1的修改結果丟失。
2.讀“髒”資料:T1修改某一資料,並將其寫回磁碟。事務T2讀取同一資料後,事務T1由於某種原因被撤銷,這時事務T1修改過的資料恢復原值,而事務T2讀取到的是一個過渡性的不再需要的“髒”資料,與資料庫中的資料不同
3.不可重複讀:事務T1讀取某一資料之後,事務T2對其進行了更改,當事務T1再次讀取該資料時,無法再現前一次讀取的結果。
4.主要原因:併發執行的事務破壞了事務的隔離性
6.3 封鎖
1.基本鎖:排它鎖(X鎖)/共享鎖(S鎖)
2.封鎖粒度:封鎖物件的大小稱為封鎖粒度
3.封鎖協議:
1)一級封鎖協議:事務T在修改資料物件之前必須對其加X鎖,直到事務結束才能釋放X鎖。
2)二級封鎖協議:在一級封鎖協議的基礎上,再進一步的規定:事務T再讀取資料物件之前必須對其加S鎖,讀完後立即釋放S鎖
3)三級封鎖協議:是在一級封鎖協議上,再進一步的規定:事務T在讀取資料物件之前必須對其加S鎖,讀完後並不立即釋放S鎖,直到事務T結束後才釋放。
4.活鎖與死鎖:
1)活鎖:是指系統中某個事務始終處於等待狀態,得不到封鎖的機會(永遠等待)
2)死鎖:如果兩個系統中有兩個或兩個以上的事務都處於等待狀態,並且每個事務都在等待其中另一個事務解除封鎖,它才能繼續執行下去,結果造成任何一個事務都無法繼續執行,這種現象稱為“死鎖”(兩個互鎖,相互等待)
(1)死鎖的預防:一次封鎖法(每個事務必須一次將所有要使用的資料全部加鎖,否則就不能繼續執行)/順序封鎖法(預先對資料物件規定一個封鎖順序,所有的事務都必須按照這個順序實行封鎖)
(2)死鎖的診斷:超時法/事務等待圖法
(3)死鎖的解除:選擇一個處理死鎖代價最小的事務,將其撤銷,釋放該事務持有的所有鎖,使其他事務得以繼續執行下去
6.4 併發排程的可序列性
1.可序列化排程:多個事務的併發執行是正確的,當且僅當其結果與按照某一次序列的執行他們時的結果相同,這種並行排程策略稱為可序列化的排程
2.衝突可序列化排程:對於時間上相鄰的兩個操作,能交換的是不衝突的操作(對同一資料,只要帶寫就衝突)
3.衝突可序列化排程:一個排程SC在保證衝突操作的次序不變的情況下,通過交換兩個事務不衝突操作的次序得到另一個排程SC’。如果SC’是序列的,那麼就稱SC是衝突可序列化的排程
6.5 兩段鎖協議
1.兩條規則:
1)在對任何資料進行讀、寫操作之前,事務首先要獲得對該資料的封鎖
2)在釋放一個封鎖之後,事務不再申請和獲得任何其他封鎖
說明:1)所謂兩段鎖協議實際上是將事務分為兩個階段,第一階段是獲得封鎖,也稱為擴充套件階段。在這個階段,事務可以申請任何資料項上的任何型別的鎖,但是不能釋放任何鎖。第二階段是釋放封鎖,也稱為收縮階段。在這個階段,事務可以釋放任何資料項上的任何型別的鎖,但是不能在申請任何鎖。
2)事務遵守兩段鎖協議是可序列化排程的充分不必要條件。