国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

MySQL InnoDB之事務與鎖詳解

2020-01-19 00:01:00
字體:
來源:轉載
供稿:網友

引題:為何引入事務?

1>.數據完整性

2>.數據安全性

3>.充分利用系統資源,提高系統并發處理的能力

1. 事務的特征

事務具有四個特性:原子性(Atomiocity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability),這四個特性簡稱ACID特性。

1.1原子性

事務是數據庫的邏輯工作單位,事務中包括的所有操作要么都做,要么都不做。

1.2 一致性

事務執行的結果必須是使數據庫從一個一致性的狀態變到另外一個一致性狀態。

1.3 隔離性

一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的數據對其他

事務是隔離的,并發執行的各個事務之間互相不干擾。

1.4 持久性

一個事務一旦成功提交,對數據庫中數據的修改就是持久性的。接下來其他的其他

操作或故障不應該對其執行結果有任何影響。

2. MySQL的InnoDB引擎中事物與鎖

2.1 SELECT …… LOCK IN SHARE MODE

會話事務中查找的數據,加上一個共享鎖。若會話事務中查找的數據已經被其他會話事務加上獨占鎖的話,共享鎖會等待其結束再加,若等待時間過長就會顯示事務需要的鎖等待超時。

2.2 SELECT ….. FOR UPDATE

會話事務中查找的數據,加上一個讀更新瑣,其他會話事務將無法再加其他鎖,必須等待其結束。

2.3 INSERT、UPDATE、DELETE

會話事務會對DML語句操作的數據加上一個獨占鎖,其他會話的事務都將會等待其釋放獨占鎖。

2.4 gap and next key lock(間隙鎖)

InnoDB引擎會自動給會話事務中的共享鎖、更新瑣以及獨占鎖,需要加到一個區間值域的時候,再加上個間隙鎖(或稱范圍鎖),對不存在的數據也鎖住,防止出現幻寫。

備注:

以上2.1,2.2,2.3,2.4中描述的情況,跟MySQL所設置的事務隔離級別也有關系。

3.四種事務隔離模式

3.1 READ UNCOMMITED

SELECT的時候允許臟讀,即SELECT會讀取其他事務修改而還沒有提交的數據。

3.2 READ COMMITED

SELECT的時候無法重復讀,即同一個事務中兩次執行同樣的查詢語句,若在第一次與第二次查詢之間時間段,其他事務又剛好修改了其查詢的數據且提交了,則兩次讀到的數據不一致。

3.3 REPEATABLE READ

SELECT的時候可以重復讀,即同一個事務中兩次執行同樣的查詢語句,得到的數據始終都是一致的。

3.4 SERIALIZABLE

與可重復讀的唯一區別是,默認把普通的SELECT語句改成SELECT …. LOCK IN SHARE MODE。即為查詢語句涉及到的數據加上共享瑣,阻塞其他事務修改真實數據。

4. 驗證事務與鎖定示例

接下來,我們將以MySQL中的InnoDB引擎,解釋其如何實現ACID特性,不同隔離級別下事務與事務之間的影響。示例表結構:

CREATE TABLE `account ` (

`ID` int(11) NOT NULL AUTO_INCREMENT,

`VACCOUNT_ID` varchar(32) NOT NULL,

`GMT_CREATE` datetime NOT NULL,

PRIMARY KEY (`ID`),

KEY `idx_VACCOUNT_PARAMETER_VACCOUNTID ` (`VACCOUNT_ID`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE utf8_general_ci;

然后向表account中寫入10W條創建日期分布合理的帳號數據,以方便測試之用。

tx_isolation:SET GLOBAL tx_isolation='read-uncommitted'
ID事務1事務1輸出事務2事務2輸出
1START TRANSACTION;   
2SELECT 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
5SELECT VACCOUNT_ID from account  where ID =1001;uncommitted  
6  ROLLBACK; 
7SELECT VACCOUNT_ID from account  where ID =1001;caimao101510  
8COMMIT;   
tx_isolation:SET GLOBAL tx_isolation='read-committed'
ID事務1事務1輸出事務2事務2輸出
1START TRANSACTION;   
2SELECT 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
6SELECT VACCOUNT_ID from account  where ID =1001;caimao101510  
7  COMMIT; 
8SELECT VACCOUNT_ID from account  where ID =1001;uncommitted  
9COMMIT;   
tx_isolation:SET GLOBAL tx_isolation='REPEATABLE-READ'
ID事務1事務1輸出事務2事務2輸出
1START TRANSACTION;   
2SELECT 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
6SELECT VACCOUNT_ID from account  where ID =1001;caimao101510  
7  COMMIT; 
8SELECT VACCOUNT_ID from account  where ID =1001;caimao101510  
9COMMIT;   
tx_isolation:SET GLOBAL tx_isolation='SERIALIZABLE'
ID事務1事務1輸出事務2事務2輸出
1START TRANSACTION;   
2SELECT VACCOUNT_ID from account  where ID =1001;caimao101510  
3  START TRANSACTION; 
4  UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001;STATE: Updating
5SELECT VACCOUNT_ID from account  where ID =1001;caimao101510  
   事務2超時 
6COMMIT;   
7START TRANSACTION;   
8UPDATE account set VACCOUNT_ID='uncommitted' where ID =1001;   
9  START TRANSACTION; 
10  SELECT VACCOUNT_ID from account  where ID =1001;STATE:statistics
11  事務2超時 
12commit;   
tx_isolation:SET GLOBAL tx_isolation='REPEATABLE-READ'
ID事務1事務1輸出事務2事務2輸出
1START TRANSACTION;   
2select max(ID) FROM account;124999  
3  START TRANSACTION; 
4UPDATE 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
11COMMIT;   
12  COMMIT; 
     
1START TRANSACTION;   
2UPDATE 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
5SELECT * 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超時 
8COMMIT;   
9  SELECT * FROM account WHERE gmt_create>'2009-07-10′ LIMIT 1;2009-10-1 13:47
無索引條件更新事務
1START 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;
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 紫云| 安仁县| 社旗县| 灌南县| 陕西省| 涟源市| 泽州县| 马龙县| 文成县| 桃源县| 玉门市| 兴城市| 公主岭市| 马山县| 金阳县| 旬邑县| 疏附县| 志丹县| 瓮安县| 隆子县| 贺兰县| 洛阳市| 化德县| 海口市| 五家渠市| 石阡县| 乳源| 康马县| 巨鹿县| 封开县| 奎屯市| 兰州市| 水富县| 句容市| 瑞安市| 玉林市| 惠东县| 大荔县| SHOW| 永兴县| 临澧县|