久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么理解Innodb一致性非鎖定讀

151次閱讀
沒有評論

共計 3302 個字符,預計需要花費 9 分鐘才能閱讀完成。

這篇文章主要講解了“怎么理解 Innodb 一致性非鎖定讀”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學習“怎么理解 Innodb 一致性非鎖定讀”吧!

一致性非鎖定讀指 InnoDB 通過多版本控制 (MVCC) 的方式在某個時間點通過查詢數據庫快照數據來讀取數據。

在 RR 事務隔離級別下,在一個事務中第一次 (select 讀) 數據的時候創建快照,快照是在第一次 select 之前所有提交的數據的最新版本的數據,在此事務結束之前,select 到的數據是一致的(快照)。

注意:Begin 和 start transaction 開啟事務的時候快照并沒有創建,而是第一次 select 讀數據時候創建。

如下:

Session A

Session B

Session A drop table t;
Session A create table t(x int primary key);
Session A insert into t values (1),(5);
Session A begin;
Session A select @@tx_isolation;
+—————–+
| @@tx_isolation  |
+—————–+
| REPEATABLE-READ |
+—————–+
Session A select * from t where x=5 for update;

上面的 for update 進行的鎖定讀,此時并沒有創建 read view 注意:for update 和 lock in share mode 都是鎖定讀,此時并不會創建快照

Session B begin;
Session B select @@tx_isolation;
+—————–+
| @@tx_isolation  |
+—————–+
| REPEATABLE-READ |
+—————–+
1 row in set (0.00 sec)
Session B insert into t select 3;
Session B commit;

Session A select * from t;  # 此時才創建 read view 生成快照
+—+
| x |
+—+
| 1 |
| 3 |
| 5 |
+—+

你可能會發現 RR 隔離級別,不是應該看不到其他事務修改的數據嗎?這正是因為 begin 開啟一個事務,不是 begin 的時候創建 read view,而是第一次進行快照讀的時候才創建

在 innodb 的 READ COMMITTED 和 REPEATABLE READ 隔離級別下執行 select 操作,默認模式就是一致性讀。

 

一致性讀不會對訪問的表加任何鎖,因此,其他會話可以任意的修改對象數據而不會影響當前會話的一致性讀。

 

在 RR 隔離級別下,某個時間點開啟一個事務 T1 查詢表的數據,接著開啟另外一個新的事務 T2 對其 delete、update、insert 數據并且 commit 成功后,在 T1 中無法看到 T2 修改并且提交的結果。

 

注意:快照讀主要適用于在一個事務中的 select 語句。所以事務中的 DML 語句是可以看到其他 session 中的事務的更新的,即時 SELECT 并不能看到這些

例如,同時開啟事務 T1、T2、T3, 在 T1 中刪除或者修改表 t 的數據,在 T2 中 select 查詢的結果(快照讀)是之前的 t 的數據(T2 事務開啟時間點的前 t 的數據), 但 T3 對表 t 修改或者刪除可能會影響剛才 T1 提交的行。

下面的例子中:Session A 只有在 Session B 的 insert 操作 commit 完成,并且 Session A 自身事務 commit 之后才能看到 Session B 插入的數據

可以使用 READ COMMITTED 或 locking read(SELECT * FROM t LOCK IN SHARE MODE;)來查看表最新的數據。

 

一致性讀不適用于特定的 DDL 語句如 DROP TABLE、ALTER TABLE。

另外,對于 INSERT INTO … SELECT, UPDATE … (SELECT)和 CREATE TABLE … SELECT 操作,雖然后面的 select 未指定 FOR UPDATE 或 LOCK IN SHARE MODE,但此時的 select 和 READ COMMIT 隔離級別下的 SELECT 一樣, 讀取最新版本數據(使用的當前讀)。

如下:

Session A

Session B

ession A create table a (x int primary key,y int);
Query OK, 0 rows affected (0.17 sec)
# 開啟一個新事務
Session A begin;
Query OK, 0 rows affected (0.00 sec)

Session A select * from a;
Empty set (0.00 sec)
# 插入數據
Session A insert into a select 1,2;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0
# 當前事務能看到 insert 的數據
Session A select * from a;
+—+——+
| x | y  |
+—+——+
| 1 |  2 |
+—+——+
1 row in set (0.00 sec)# 暫時不 commit

# 在 A 提交之前,B 開啟事務     Session B begin;
Query OK, 0 rows affected (0.00 sec)
# 此時查詢表 a 的數據,一致性非鎖定讀,讀到的是事務開啟前已經提交的數據,因為 B 的事務開始的時候 A 事務還沒有提交,故 A 中 insert 的數據不會顯示
Session B select * from a;
Empty set (0.00 sec)

#session A 提交上面的事務   Session A commit;
Query OK, 0 rows affected (0.00 sec)

# 在 B 中 select 查詢,依舊進行的是快照讀,故看不到數據   Seesion B select * from a;
Empty set (0.00 sec)

Seesion B select * from aa;
Empty set (0.00 sec)
#INSERT INTO … SELECT * FROM A; 操作
Seesion B insert into aa select * from a;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Seesion B select * from a;
Empty set (0.00 sec)
# 發現直接 select 表 a 還是查不到數據,而 aa 表能看到數據
Seesion B select * from aa;
+—+——+
| x | y  |
+—+——+
| 1 |  2 |
+—+——+
1 row in set (0.00 sec)

# 使用 lock in share mode 或 for update 進行當前讀能看到表 a 的數據
Seesion B select * from a lock in share mode;
+—+——+
| x | y  |
+—+——+
| 1 |  2 |
+—+——+
1 row in set (0.00 sec)

Seesion B select * from a;
Empty set (0.00 sec)
Seesion B select * from a for update;
+—+——+
| x | y  |
+—+——+
| 1 |  2 |
+—+——+
1 row in set (0.00 sec)

當 innodb_locks_unsafe_for_binlog 選項為 1 時(關閉 GAP 鎖),在 READ UNCOMMITTED, READ COMMITTED, REPEATABLEREAD 隔離級別下,select 查詢表的數據,不會對數據進行鎖定,而都是一致性讀。
感謝各位的閱讀,以上就是“怎么理解 Innodb 一致性非鎖定讀”的內容了,經過本文的學習后,相信大家對怎么理解 Innodb 一致性非鎖定讀這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關知識點的文章,歡迎關注!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-19發表,共計3302字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 遵化市| 桃园市| 沙湾县| 清远市| 新巴尔虎右旗| 昌吉市| 雅安市| 含山县| 全椒县| 柞水县| 独山县| 茌平县| 连平县| 周至县| 利辛县| 长汀县| 德令哈市| 缙云县| 广东省| 崇左市| 凌海市| 苏州市| 武城县| 正宁县| 浦东新区| 炎陵县| 嘉祥县| 连云港市| 信丰县| 二连浩特市| 玛曲县| 巴青县| 册亨县| 平原县| 论坛| 龙州县| 安平县| 铜川市| 山西省| 灌云县| 常德市|