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

怎么在mysql中實現事務的隔離級別

136次閱讀
沒有評論

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

自動寫代碼機器人,免費開通

這篇文章給大家介紹怎么在 mysql 中實現事務的隔離級別,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

事務就是一組一起成功或一起失敗的 sql 語句。事務還應該具備,原子性,一致性,隔離性和持久性。

一、事務的基本要素 (ACID)

1、原子性:事務開始后,所有的操作,要么全部成功,要么全部失敗,不可能處于中間狀態,事務是一個不可分割的整體,就像原子一樣。

2、一致性:事務開始前和結束后,數據庫的完整性約束沒有破壞,A 向 B 轉賬,A 扣了錢,但 B 卻沒到賬。

3、隔離性:同時發生的事務 (并發事務) 不應該導致數據庫處于不一致的狀態中,每個事務都獨立執行,不影響其他事務的存在。

4、持久性:事務對數據庫的更改都會保存在磁盤上,不會丟失。

二、事務的并發問題

1、臟讀:事務 A 讀取了事務 B 未提交的寫入數據,讀取到的數據就稱為臟數據

2、不可重復讀:事務 A 多次讀取同一數據,但在讀取過程中,事務 B 對數據做了修改,并提交了。導致多次讀取同一數據,結果不一樣。

3、幻讀:事務 A 對表中所有數據行進行了修改,比如設置 status = 1,但同時,事務 B 往該表插入了一行新數據 status = 0,對于操作事務 A 的用戶而言,表中還有一條記錄沒被修改,就像發生幻覺一樣。

三、事務隔離性的四個級別

事務隔離級別臟讀不可重復讀幻讀讀取未提交 read uncommitted√√√讀已提交 read committed×√√可重復讀取 repeatable read××√序列化 serializable×××

四、獲取和設置數據庫隔離級別

SHOW VARIABLES LIKE  %isolation% 
SHOW GLOBAL VARIABLES LIKE  %isolation%

使用系統變量查詢

SELECT @@GLOBAL.tx_isolation;
SELECT @@SESSION.tx_isolation;
SELECT @@tx_isolation;

對于 mysql8 而言,使用下面的變量進行查詢

SELECT @@GLOBAL.transaction_isolation;
SELECT @@SESSION.transaction_isolation;
SELECT @@transaction_isolation;

設置隔離級別

SET GLOBAL tx_isolation =  隔離級別 
SET SESSION tx_isolation =  隔離級別 
SET @@tx_isolation =  隔離級別

對于 mysql8 而言,使用下面語句進行設置

SET GLOBAL transaction_isolation =  隔離級別 
SET SESSION transaction_isolation =  隔離級別 
SET @@transaction_isolation =  隔離級別

五、通過例子說明各隔離級別的情況

先準備一張表,和一點數據。

CREATE TABLE `account` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT  ID ,
 `name` varchar(32) DEFAULT   COMMENT  名稱 ,
 `money` decimal(11,2) DEFAULT  0.00  COMMENT  金錢 ,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `account` (`name`, `money`) VALUES ( A ,  500.00 
INSERT INTO `account` (`name`, `money`) VALUES (B ,  100.00

1、讀取未提交

set transaction_isolation =  READ-UNCOMMITTED 
set autocommit = 0;

怎么在 mysql 中實現事務的隔離級別

事務 B 修改了表中的數據,但是未提交,事務 A 確讀取到了修改后的數據。如果因為某些原因,事務 B 回滾了,事務 A 讀取的這個數據就是臟數據。

2、讀已提交

set transaction_isolation =  READ-COMMITTED 
set autocommit = 0;

怎么在 mysql 中實現事務的隔離級別

事務 B 修改數據但沒有提交,那么事務 A 仍然獲取的原來數據,解決了臟讀的問題。

但是事務 B 提交,事務 A 執行上一次查詢,結果與上一次查詢不一致,這就產生不可重復讀的問題。

怎么在 mysql 中實現事務的隔離級別

3、可重復讀取

set transaction_isolation =  REPEATABLE-READ 
set autocommit = 0;

怎么在 mysql 中實現事務的隔離級別

事務 B 修改了數據并提交了,事務 A 兩次查詢的結果是一致的,解決了不可重復讀的問題。

這個時候,事務 A 去修改 name 為 A 的 money 數據

怎么在 mysql 中實現事務的隔離級別

name 為 A 的 money 變成了 350,而不是 400,可重復讀保證了數據的一致性。

我們重新在事務 A 中修改所有賬號的 money 等于 200,同時在事務 B 中插入一條新的數據。

怎么在 mysql 中實現事務的隔離級別

事務 A 中獲取的仍然是兩條數據,解決了新增數據時,事務 A 出現的幻讀問題。

4、序列化

set transaction_isolation =  SERIALIZABLE 
set autocommit = 0;

怎么在 mysql 中實現事務的隔離級別

事務 A 對表進行查詢,如果沒有提交,則事務 B 的插入語句一直等待在那里,直到超時或事務 A 提交。

反之,事務 B 對表進行插入后,沒有提交,則事務 A 對表的查詢也一直等待,直到事務 B 提交。

此時對表的讀寫都會進行鎖表,當然對并發性能的影響也比較大。

隔離級別越高,越能保證數據的完整性和一致性。

六、mysql 的鎖

鎖分為兩種類型:

內部鎖:mysql 服務器內部執行的內部鎖,以管理多個會話對表內容的爭用。

外部鎖:mysql 為客戶會話提供顯式地獲取表鎖,以阻止其他會話訪問表。

內部鎖又會為兩種類型:

1、行級鎖:行級鎖是細粒度的,只有被訪問的行會被鎖定,這允許多個會話同時進行寫訪問。

2、表級鎖:mysql 對 myisam,memory 和 merge 表使用表級鎖,一次只允許一個會話更新表,這使得這些存儲引擎更適用于以讀取為主的操作。

外部鎖:可以使用 LOCK TABLE 和 UNLOCK TABLE 來控制鎖定。

READ (共享鎖):多個會話可以從表中讀取數據而不需要獲取鎖,此外,多個會話可以在同一表上獲得鎖,當 READ 鎖時,沒有會話可以將數據寫入表中。任何寫入操作都將處于等待狀態,直到 READ 鎖被釋放。

WRITE (排他鎖):當表被 WRITE 鎖定時,除持有該鎖的會話外,其他會話都不能讀取或寫入數據,除非 WRITE 鎖被釋放。

鎖表的語句:

LOCK TABLES table_name [READ | WRITE];

解鎖表的語句:

UNLOCK TABLES;

鎖定數據庫中所有表:

FLUSH TABLES WITH READ LOCK;

關于怎么在 mysql 中實現事務的隔離級別就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向 AI 問一下細節

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-12-04發表,共計2877字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 平湖市| 沙雅县| 台安县| 临潭县| 罗田县| 遂宁市| 东安县| 泰顺县| 东阳市| 海晏县| 乐山市| 连南| 环江| 靖安县| 莆田市| 越西县| 新巴尔虎右旗| 贵溪市| 崇文区| 庆元县| 波密县| 腾冲县| 昂仁县| 寿光市| 北海市| 肥乡县| 保康县| 德安县| 云霄县| 西丰县| 南雄市| 保德县| 陵川县| 拉萨市| 汤原县| 新津县| 宜良县| 宜黄县| 日照市| 夏津县| 北票市|