MySql學習之事務和併發控制

數據庫模型:

這裏寫圖片描述

ACID:

原子性(automicity):一個事務必須被看作一個不可分割的最小單元。對於事務裏的操作要麼全部成功,要麼全部失敗,不可能執行其中一部分。這就是事務的原子性。
一致性(consistency):數據庫總是從一個一致性的狀態轉換到另外一個一致性的狀態。在事務沒有提交之前,事務中做出的修改不會被保存到數據庫中。
隔離性(isolation):通常來說,一個事務做的修改,對於其他事務是不可見的。當然這取決於隔離的級別。
持久性(durability):一旦事務提交,數據將會被永久地保存在數據庫中,永遠保存在數據庫。

數據庫隔離的級別:

1、未提交可讀:A事務修改某條記錄,未提交;B事務可以讀取A事務修改後的該條記錄數據值。
2、提交可讀(不可重複讀):A事務第一次讀取某條記錄後,B事務修改該條記錄且提交,A事務再次讀取該條記錄,A事務2次讀取的值不同。
3、可重複讀:A事務第一次讀取某條記錄後,B事務修改該條記錄且提交,A事務再次讀取該條記錄,A事務2次讀取的值相同。
該級別無法防住“幻讀”,即A事務第一次讀取某個範圍記錄中,B事務在該範圍新增一條記錄且提交,A事務再次讀取該範圍記錄時,A事務第2次讀取的範圍值會多一行。
4、可串行化:強制事務串行執行,避免了幻讀的問題。該方式是在每一行都加鎖,所以可能會存在大量的超時和鎖競爭,一般很少用這個級別,
只用必須保證數據的一致性且可以接受不需要併發的場景纔會使用。

死鎖:

是指兩個或多個事務在同一個資源上的相互佔用,並請求鎖定對方的資源,從而導致惡性循環的現象。當多個事務試圖以不同的順序鎖定資源時,就會產生死鎖,
多個事務鎖定同一個資源也會產生死鎖。
比如下面兩個事務:
事務1:
START TRANSACTION;
UPDATE T_ACCOUNT SET ACCOUNT_NO = 55555 WHERE ID = 3;
UPDATE T_ACCOUNT SET ACCOUNT_NO = 33333 WHERE ID = 4;
COMMIT;

事務2:
START TRANSACTION;
UPDATE T_ACCOUNT SET ACCOUNT_NO = 33333 WHERE ID = 4;
UPDATE T_ACCOUNT SET ACCOUNT_NO = 55555 WHERE ID = 3;
COMMIT;

如果湊巧,兩個事務都執行了第一條UPDATE語句,更新了一行數據且同時鎖定了該行數據,接着同時去UPDATE第二條語句會發現對方被鎖定,等待獲得鎖,進而進入死循環。
爲了解決這個問題,數據庫系統實現了各種死鎖檢測和死鎖超時檢測機制。越複雜的系統,比如InnoDB存儲引擎,越能檢測出死鎖的循環依賴,並返回一個錯誤。這種解決
方式很有效,否則會出現非常慢的查詢。還有一種解決方式,就是在查詢的時候達到鎖的超時時間的設定後放棄鎖請求,這種方式通常來說不太好。InnoDB目前處理死鎖的
方式是:將持有最少行級排它鎖的事務進行回滾。

MYSQL採用自動提交模式。如果不是顯示開始一個事務,則每個查詢都被當做一個事務執行提交操作。在當前連接中,可以通過設置AUTOCOMMIT變量來啓用或禁用自動提交模式。
查看自動提交是否開啓:SHOW VARIABLES LIKE ‘AUTOCOMMIT’;
1或者ON表示開啓,0或者OFF表示關閉:SET AUTOCOMMIT = ‘1’;

設置全局的事務隔離級別:SET TRANSACTION ISOLATION LEVEL READ COMMIT;
設置當前會話的事務隔離級別:SET SESSION TRANSACTION ISOLATION LEVEL READ COMMIT;

InnoDB的多版本併發控制(MVCC):

MVCC是行級鎖的一個變種,但它在很多情況下避免了加鎖的操作,因此開銷更低。雖然實現機制有所不同,但大都實現了非阻塞的讀操作,寫操作也只鎖定必要的行。
MVCC的實現,是通過保存數據在某個時間點的快照來實現的。也就是說,不管需要執行多長時間,每個事務看到的數據都是一致的。根據事務開始的時間不同,每個
事務對同一張表,同一時刻看到的數據可能是不一樣的。
InnoDB的MVCC是通過在每行記錄後面保存兩個隱藏的列來實現的。這兩個列,一個保存了行的創建時間,一個保存行的過期時間(或刪除時間)。當然存儲的並不是實際
的時間值,而是系統版本號。沒開始一個事務,系統版本號都會自動遞增。事務開始時刻的系統版本號會作爲事務的版本號,用來和查詢到的每行記錄的版本號作爲比
較。下面看一下可重複讀隔離級別下,MVCC如何操作的:
1、SELECT
InnoDB會根據一下兩個條件檢查記錄
a.InnoDB只會查找版本早於當前事務版本的行(也就是行的系統版本號小於或等於當前事務的系統版本號),這樣可以確保事務讀取的行,要麼在事務開始前已經存在,要
麼是事務自身插入或者修改的。
b.行的刪除版本號要麼未定義,要麼大於當前事務版本號。這可以確保事務讀取到的行,在事務開始前未被刪除。
2、INSERT
InnoDB爲新插入的每一行保存當前系統版本號作爲行版本號。
3、DELETE
InnoDB爲刪除的每一行保存當前系統版本號作爲刪除標誌。
4、InnoDB爲插入一行新紀錄,保存當前系統版本號作爲行版本號,同時保存當前系統版本號到原來的行作爲行刪除標誌。

使用這2個額外系統版本號,使大多數讀操作都可以不用加鎖。這使大多數讀操作都可以不用加讀鎖。這樣設計使得讀數據操作更簡單,性能更好,並且能保證讀取的準確性。
不足之處是需要額外的存儲空間,需要做更多的行檢查工作。MVCC只在不可重複讀和可重複讀兩個隔離級別下工作。

在文件系統中,MYSQL將每個數據庫(也可稱schema)保存爲數據目錄下的一個子目錄。創建表時,MYSQL會在數據庫子目錄下創建一個和表同名的.frm文件保存表的定義。例如創建
一個名爲MyTable的表,MYSQL會將MyTable.frm文件中保存該表的定義。因爲MYSQL使用文件系統的目錄和文件來保存數據庫和表的定義,大小寫敏感和具體的平臺有關。
查詢表的基本信息:

select * from information_schema.TABLES where information_schema.TABLES.TABLE_SCHEMA = '庫名' and information_schema.TABLES.TABLE_NAME = '表名';

Name:表名
Engine:表的存儲引擎類型。
Row_format:行的格式。對於MyISAM表,可選的值爲Dynamic、Fixed、Compressed。Dynamic的長度是可變的,一般包含可變長度的字段,比如VARCHAR或BLOB。Fixed的行長度則是
固定的,只包含固定長度的列,如CHAR、INTEGER。Compressed的則只在壓縮表中存在。
Rows:表中的行數。對於MyISAM和其他一些引擎,該值是精確的,但對於InnoDB,該值是估計值。
Avg_row_length:平均每行包含的字節數。
Data_length:表數據的大小(以字節爲單位)。
Max_data_length:表的最大容量,該值和存儲引擎有關。
Index_length:索引的大小(以字節爲單位)。
Data_free:對於MyISAM表,表示已分配但目前沒有使用的空間。這部分空間包括了之前刪除的行,以及後續可以被INSERT利用到的空間。
Auto_increment:下一個AUTO_INCREMENT的值。
Create_time:表的創建時間。
Update_time:表的最後修改時間。
Check_time:使用CHECK TABLE命令或者工具最後一次檢查表的時間。
Collation:表的默認字符集和字符排列規則。
Checksum:如果開啓,保存的是整個表的實時校驗和。
Create_options:創建表指定的其他選項。
Comment:該列包含了一些其他的額外信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章