《Mysql學習MySQL InnoDB之事務與鎖詳解》要點:
本文介紹了Mysql學習MySQL InnoDB之事務與鎖詳解,希望對您有用。如果有疑問,可以聯系我們。
引題:為何引入事務?MYSQL教程
1>.數據完整性MYSQL教程
2>.數據安全性MYSQL教程
3>.充分利用系統資源,提高系統并發處理的能力MYSQL教程
1.?事務的特征MYSQL教程
事務具有四個特性:原子性(Atomiocity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability),這四個特性簡稱ACID特性.MYSQL教程
1.1原子性MYSQL教程
事務是數據庫的邏輯工作單位,事務中包括的所有操作要么都做,要么都不做.MYSQL教程
1.2?一致性MYSQL教程
事務執行的結果必須是使數據庫從一個一致性的狀態變到另外一個一致性狀態.MYSQL教程
1.3?隔離性MYSQL教程
一個事務的執行不能被其他事務干擾.即一個事務內部的操作及使用的數據對其他MYSQL教程
事務是隔離的,并發執行的各個事務之間互相不干擾.MYSQL教程
1.4?持久性MYSQL教程
一個事務一旦成功提交,對數據庫中數據的修改就是持久性的.接下來其他的其他MYSQL教程
操作或故障不應該對其執行結果有任何影響.MYSQL教程
2. MySQL的InnoDB引擎中事物與鎖MYSQL教程
2.1 SELECT …… LOCK IN SHARE MODEMYSQL教程
會話事務中查找的數據,加上一個共享鎖.若會話事務中查找的數據已經被其他會話事務加上獨占鎖的話,共享鎖會等待其結束再加,若等待時間過長就會顯示事務需要的鎖等待超時.MYSQL教程
2.2 SELECT ….. FOR UPDATEMYSQL教程
會話事務中查找的數據,加上一個讀更新瑣,其他會話事務將無法再加其他鎖,必須等待其結束.MYSQL教程
2.3 INSERT、UPDATE、DELETEMYSQL教程
會話事務會對DML語句操作的數據加上一個獨占鎖,其他會話的事務都將會等待其釋放獨占鎖.MYSQL教程
2.4 gap and next key lock(間隙鎖)MYSQL教程
InnoDB引擎會自動給會話事務中的共享鎖、更新瑣以及獨占鎖,需要加到一個區間值域的時候,再加上個間隙鎖(或稱范圍鎖),對不存在的數據也鎖住,防止出現幻寫.MYSQL教程
備注:MYSQL教程
以上2.1,2.2,2.3,2.4中描述的情況,跟MySQL所設置的事務隔離級別也有關系.MYSQL教程
3.四種事務隔離模式MYSQL教程
3.1 READ UNCOMMITEDMYSQL教程
SELECT的時候允許臟讀,即SELECT會讀取其他事務修改而還沒有提交的數據.MYSQL教程
3.2 READ COMMITEDMYSQL教程
SELECT的時候無法重復讀,即同一個事務中兩次執行同樣的查詢語句,若在第一次與第二次查詢之間時間段,其他事務又剛好修改了其查詢的數據且提交了,則兩次讀到的數據不一致.MYSQL教程
3.3 REPEATABLE READMYSQL教程
SELECT的時候可以重復讀,即同一個事務中兩次執行同樣的查詢語句,得到的數據始終都是一致的.MYSQL教程
3.4 SERIALIZABLEMYSQL教程
與可重復讀的唯一區別是,默認把普通的SELECT語句改成SELECT …. LOCK IN SHARE MODE.即為查詢語句涉及到的數據加上共享瑣,阻塞其他事務修改真實數據.MYSQL教程
4.?驗證事務與鎖定示例MYSQL教程
接下來,我們將以MySQL中的InnoDB引擎,解釋其如何實現ACID特性,不同隔離級別下事務與事務之間的影響.示例表結構:MYSQL教程
CREATE TABLE `account ` (MYSQL教程
`ID` int(11) NOT NULL AUTO_INCREMENT,MYSQL教程
`VACCOUNT_ID` varchar(32) NOT NULL,MYSQL教程
`GMT_CREATE` datetime NOT NULL,MYSQL教程
PRIMARY KEY (`ID`),MYSQL教程
KEY `idx_VACCOUNT_PARAMETER_VACCOUNTID ` (`VACCOUNT_ID`)MYSQL教程
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE utf8_general_ci;MYSQL教程
然后向表account中寫入10W條創建日期分布合理的帳號數據,以方便測試之用.MYSQL教程
tx_isolation:SET GLOBAL tx_isolation='read-uncommitted' | ||||
ID | 事務1 | 事務1輸出 | 事務2 | 事務2輸出 |
1 | START TRANSACTION; | ? | ? | ? |
2 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
? | ? | ? | START TRANSACTION; | ? |
3 | ? | ? | UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001; | ? |
4 | ? | ? | SELECT VACCOUNT_ID from account? where ID =1001; | uncommitted |
5 | SELECT VACCOUNT_ID from account? where ID =1001; | uncommitted | ? | ? |
6 | ? | ? | ROLLBACK; | ? |
7 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
8 | COMMIT; | ? | ? | ? |
tx_isolation:SET GLOBAL tx_isolation='read-committed' | ||||
ID | 事務1 | 事務1輸出 | 事務2 | 事務2輸出 |
1 | START TRANSACTION; | ? | ? | ? |
2 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
3 | ? | ? | START TRANSACTION; | ? |
4 | ? | ? | UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001; | ? |
5 | ? | ? | SELECT VACCOUNT_ID from account? where ID =1001; | uncommitted |
6 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
7 | ? | ? | COMMIT; | ? |
8 | SELECT VACCOUNT_ID from account? where ID =1001; | uncommitted | ? | ? |
9 | COMMIT; | ? | ? | ? |
tx_isolation:SET GLOBAL tx_isolation='REPEATABLE-READ' | ||||
ID | 事務1 | 事務1輸出 | 事務2 | 事務2輸出 |
1 | START TRANSACTION; | ? | ? | ? |
2 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
3 | ? | ? | START TRANSACTION; | ? |
4 | ? | ? | UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001; | ? |
5 | ? | ? | SELECT VACCOUNT_ID from account? where ID =1001; | uncommitted |
6 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
7 | ? | ? | COMMIT; | ? |
8 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
9 | COMMIT; | ? | ? | ? |
tx_isolation:SET GLOBAL tx_isolation='SERIALIZABLE' | ||||
ID | 事務1 | 事務1輸出 | 事務2 | 事務2輸出 |
1 | START TRANSACTION; | ? | ? | ? |
2 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
3 | ? | ? | START TRANSACTION; | ? |
4 | ? | ? | UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001; | STATE: Updating |
5 | SELECT VACCOUNT_ID from account? where ID =1001; | caimao101510 | ? | ? |
? | ? | ? | 事務2超時 | ? |
6 | COMMIT; | ? | ? | ? |
7 | START TRANSACTION; | ? | ? | ? |
8 | UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001; | ? | ? | ? |
9 | ? | ? | START TRANSACTION; | ? |
10 | ? | ? | SELECT VACCOUNT_ID from account? where ID =1001; | STATE:statistics |
11 | ? | ? | 事務2超時 | ? |
12 | commit; | ? | ? | ? |
tx_isolation:SET GLOBAL tx_isolation='REPEATABLE-READ' | ||||
ID | 事務1 | 事務1輸出 | 事務2 | 事務2輸出 |
1 | START TRANSACTION; | ? | ? | ? |
2 | select max(ID) FROM account; | 124999 | ? | ? |
3 | ? | ? | START TRANSACTION; | ? |
4 | UPDATE account set gmt_create=date_add(gmt_create,interval +1 day) WHERE ID >=124999; | ? | ? | ? |
5 | ? | ? | insert into account(VACCOUNT_ID,gmt_create) values(‘eugene',now()); | STATE:update |
6 | ? | ? | 事務2超時 | ? |
7 | ? | ? | START TRANSACTION; | ? |
8 | ? | ? | SELECT * FROM account WHERE ID =124998; | 2007-10-20 13:47 |
9 | ? | ? | UPDATE account set gmt_create=date_add(gmt_create,interval +1 day) WHERE ID =124998; | 執行成功 |
10 | ? | ? | SELECT * FROM account WHERE ID =124998; | 2007-10-21 13:47 |
11 | COMMIT; | ? | ? | ? |
12 | ? | ? | COMMIT; | ? |
? | ? | ? | ? | ? |
1 | START TRANSACTION; | ? | ? | ? |
2 | UPDATE account set gmt_create=date_add(gmt_create,interval -1 day) WHERE gmt_create >'2009-07-01′; | ? | ? | ? |
3 | ? | ? | START TRANSACTION; | ? |
4 | ? | ? | SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1; | 2009-10-2 13:47 |
5 | SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1; | 2009-10-1 13:47 | ? | STATE:update |
6 | ? | ? | insert into account(VACCOUNT_ID,gmt_create) values(‘gmt_create_test',now()); | ? |
7 | ? | ? | 事務2超時 | ? |
8 | COMMIT; | ? | ? | ? |
9 | ? | ? | SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1; | 2009-10-1 13:47 |
無索引條件更新事務 | ||||
1 | START TRANSACTION; | ? | ? | ? |
? | UPDATE account set gmt_create=date_add(gmt_create,interval -1 day) WHERE gmt_create >'2009-07-01′ AND gmt_create <'2009-07-10′; | ? | ? | ? |
? | ? | ? | START TRANSACTION; | ? |
? | ? | ? | insert into account(VACCOUNT_ID,gmt_create) values(‘gmt_create_interval',now()); | ? |
? | ? | ? | 事務2超時 | ? |
? | COMMIT; |
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/3537.html