【MySQL】事務及隔離性

目錄

一、什么是事務

(一)概念

(二)事務的四大屬性

(三)事務的作用

(四)事務的提交方式

二、事務的啟動、回滾與提交

(一)事務的啟動、回滾與提交

(二)特殊情況

1、未 commit 事務,客戶端崩潰,MySQL將自動回滾

2、commit 后,客戶端崩潰,插入數據不受影響

3、手動開啟事務不受自動提交事務影響

4、自動提交事務對單條?SQL 語句的影響

5、結論

三、事務的隔離級別

(二)事務的隔離級別

(三)四種隔離級別詳解

1、讀未提交

2、讀已提交

3、可重復讀

4、串行化


一、什么是事務

(一)概念

????????MySQL 事務是指數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成,這些操作要么全部執行成功,要么全部不執行,是一個不可分割的工作單位。事務主要用于保證數據的一致性和完整性,特別是在需要多個操作同時成功或同時失敗的場景中,比如銀行轉賬、訂單處理等。

(二)事務的四大屬性

? ? ? ? 事務的特性:

  • 原子性:事務中的所有操作要么全部完成,要么全部不完成,不會結束在中間某個狀態;
  • 一致性:事務必須使數據庫從一個一致性狀態變換到另一個一致性狀態;
  • 隔離性:多個事務并發執行時,一個事務的執行不會影響其他事務;
  • 持久性:一旦事務提交,其結果就是永久性的,即使系統崩潰也不會丟失。

(三)事務的作用

? ? ? ? 事務的出現是為了簡化程序開發時可能需要考慮的多種細節問題。例如:當銀行賬戶 A 向銀行賬戶 B 發起轉賬,首先需要現在 A 中扣除目標金額后再向B中添加目標金額,假如在扣除A賬戶的金額后出現了網絡異常導致轉賬失敗,這時的正常情況應該是賬戶A上返回了目標金額,事務的出現就使得該操作可以由 MySQL 自動完成而不需要程序員特殊處理。

(四)事務的提交方式

? ? ? ? 事務的提交方式分為自動提交和手動提交。在先前學習MySQL語句時并沒有對事務進行過特殊操作,這是因為 MySQL 默認設置自動提交。也就是每當執行一條語句后 MySQL自動將該語句進行事務的提交。

? ? ? ? 查看事務自動提交方式:

//MySQl 默認打開自動提交
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.02 sec)
//設置自動提交事務關閉
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

二、事務的啟動、回滾與提交

? ? ? ? 為方便演示,需關閉事務自動提交、將事務的隔離級別設為最低并準備一個測試表:

//打開事務自動提交
mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)
//設置隔離級別(需重啟終端)
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
//創建測試表
mysql> create table test(-> id int primary key,-> name varchar(20) not null,-> salary decimal(10,2) default 0.0-> );
Query OK, 0 rows affected (0.02 sec)

(一)事務的啟動、回滾與提交

//手動開啟事務 (手動開始事務后該事務不受自動提交影響)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
//保存點1
mysql> savepoint save1;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(1,'張三',5000);
Query OK, 1 row affected (0.00 sec)
//保存點2
mysql> savepoint save2;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(2,'李四',4500);
Query OK, 1 row affected (0.00 sec)
//此時有兩條記錄
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)
//回滾至保存點2
mysql> rollback to save2;
Query OK, 0 rows affected (0.00 sec)
//此時變為一條記錄
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
+----+--------+---------+
1 row in set (0.00 sec)
//回滾至最開始
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
//無記錄
mysql> select * from test;
Empty set (0.00 sec)

? ? ? ? 由上述結果可以看出,手動開啟事務后將不受自動提交的影響。以上便是手動開啟事務以及回滾操作。

(二)特殊情況

? ? ? ? 以下情況都是最低隔離級別下的操作(讀未提交),為方便說明開啟兩個終端進行演示:

1、未 commit 事務,客戶端崩潰,MySQL將自動回滾

//客戶端A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(1, '張三', 5000);
Query OK, 1 row affected (0.00 sec)mysql> insert into test values(2, '李四', 4500);
Query OK, 1 row affected (0.00 sec)mysql> Aborted
[X@centos-414 ~]$ //客戶端B
mysql> select * from test;
Empty set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
+----+--------+---------+
1 row in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
Empty set (0.01 sec)

2、commit 后,客戶端崩潰,插入數據不受影響

//客戶端A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(1, '張三', 5000);
Query OK, 1 row affected (0.00 sec)mysql> insert into test values(2, '李四', 4500);
Query OK, 1 row affected (0.00 sec)mysql> commit;
Query OK, 0 rows affected (0.00 sec)mysql> Aborted//客戶端B
mysql> select * from test;
Empty set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
+----+--------+---------+
1 row in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)

3、手動開啟事務不受自動提交事務影響

//客戶端A
mysql> set autocommit=1;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> insert into test values(3, '王五', 5500);
Query OK, 1 row affected (0.00 sec)mysql> Aborted//客戶端B
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
|  3 | 王五   | 5500.00 |
+----+--------+---------+
3 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.01 sec)

4、自動提交事務對單條?SQL 語句的影響

//客戶端A
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | OFF   |
+---------------+-------+
1 row in set (0.00 sec)mysql> insert into test values(3, '王五', 5500);
Query OK, 1 row affected (0.00 sec)mysql> Aborted//客戶端B
mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
|  3 | 王五   | 5500.00 |
+----+--------+---------+
3 rows in set (0.00 sec)mysql> select * from test;
+----+--------+---------+
| id | name   | salary  |
+----+--------+---------+
|  1 | 張三   | 5000.00 |
|  2 | 李四   | 4500.00 |
+----+--------+---------+
2 rows in set (0.00 sec)

5、結論

  • 只要輸入 begin 或者 start transaction,事務就必須通過 commit 提交才會持久化,與是否設置自動提交無關;
  • 對于 InnoDB 每一條 SQL 語言都默認封裝成事務,自動提交。(select有特殊情況,因為 MySQL 有 MVCC );
  • 如果沒有設置保存點,也可以回滾,只能回滾到事務的開始。直接使用 rollback(前提是事務還沒有提交)
  • 如果一個事務被提交了則無法回退;
  • InnoDB 支持事務, MyISAM 不支持事務

三、事務的隔離級別

(一)什么是隔離性

????????事務的隔離性是數據庫事務的四大特性之一,它確保并發執行的多個事務相互獨立,一個事務的操作不會被其他事務干擾,從而避免數據不一致問題。隔離性通過不同的隔離級別來控制事務之間的可見性和影響程度。

? ? ? ? 查看隔離級別:

//查看全局隔離級別(一般默認為REPEATABLE-READ)
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED      |
+-----------------------+
1 row in set, 1 warning (0.01 sec)
//查看此次會話隔離級別(一般開啟MySQL客戶端后該值由全局隔離級別進行初始化)
mysql> select @@session.tx_isolation;
+------------------------+
| @@session.tx_isolation |
+------------------------+
| READ-UNCOMMITTED       |
+------------------------+
1 row in set, 1 warning (0.00 sec)
//查看此次會話隔離級別
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation   |
+------------------+
| READ-UNCOMMITTED |
+------------------+
1 row in set, 1 warning (0.00 sec)

? ? ? ? 在使用MySQL客戶端時的隔離級別由會話隔離級別等級決定。

? ? ? ? 設置隔離級別:

//設置會話隔離級別
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED      |
+-----------------------+
1 row in set, 1 warning (0.00 sec)mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| SERIALIZABLE   |
+----------------+
1 row in set, 1 warning (0.00 sec)

(二)事務的隔離級別

? ? ? ? SQL標準定義了四種隔離級別:

  1. 讀未提交
    允許事務讀取其他事務未提交的數據,可能出現臟讀、不可重復讀和幻讀的情況;
  2. 讀已提交
    只允許讀取已提交的數據,避免臟讀,但存在不可重復讀和幻讀的情況;
  3. 可重復讀
    確保同一事務多次讀取同一數據結果的一致性,可能會出現幻讀的情況;
  4. 串行化
    最高隔離的級別,事務完全串行化,可避免所有并發問題,但性能低。

(三)四種隔離級別詳解

1、讀未提交

????????在多個并行的會話中啟動事務,一個事務在改動數據庫哪怕沒有commit提交,其他事務也是能夠實時的看到它修改的數據。一個事務在執行中,讀到另一個執行中事務的更新(或其他操作)但是未commit的數據,這種不合理的現象叫做臟讀(dirty read)。

? ? ? ? 上圖可以看出,即使左端事務沒有進行提交操作,但右端事務仍可以看到表的操作,這就是臟讀。

2、讀已提交

????????事務A在commit提交事務之前,所做的修改是不會被其他事務看到的,一旦事務A發起commit之后,其他事務就能看到事務A對數據的修改。這就造成了其他事務在不同的時間點select查看數據庫時,會查到不同的數據。這種現象叫不可重復讀

? ? ? ? 上圖可知,只要事務的操作被提交,那么其他事務可以查看到該事務的插入操作,這就會導致其他事務對同一表的查詢結果可能會發生變化,這就是不可重復讀。

3、可重復讀

????????可重復讀是MySQL默認的隔離級別。

? ? ? ? 上圖可知,即使事務的操作被提交,其他事務仍然無法查看到該事務對表的操作,只要其他事務也提交以后才能查看到其他事務對表的操作。

4、串行化

????????串行化就是對所有事務進行加鎖,事務的執行(一般對查詢操作不進行加鎖)全部挨個排隊,這就導致了效率低下問題。

????????開啟事務A和事務B,兩個事務同時select讀取將使用共享鎖,不會串行化;事務A中有更新等操作,會阻塞A,直到事務B提交。如果事務A阻塞時間過長,將會由于鎖等待超時退出當前事務。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85348.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85348.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85348.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

視覺分析明火檢測助力山東化工廠火情防控

視覺分析技術賦能化工廠火情防控:從山東事故看明火與煙霧檢測的應用價值 一、背景:山東化工事故中的火情防控痛點 近期,山東高密友道化學有限公司、淄博潤興化工科技有限公司等企業接連發生爆炸事故,暴露出傳統火情防控手段的局…

【小程序】微信小程序備案失敗,有請DeepSeek閃亮出場,看TA如何快速給出解決方案

🌹歡迎來到《小5講堂》🌹 🌹這是《小程序》系列文章,每篇文章將以博主理解的角度展開講解。🌹 🌹溫馨提示:博主能力有限,理解水平有限,若有不對之處望指正!&a…

Oracle正則表達式學習

目錄 一、正則表達簡介 二、REGEXP_LIKE(x,匹配項) 三、REGEXP_INSTR 四、REGEXP_SUBSTR 五、REGEXP_REPLACE 一、正則表達簡介 相關網址: https://cloud.tencent.com/developer/article/1456428 https://www.cnblogs.com/lxl57610/p/8227599.html https://…

vscode 代理模式(agent mode),簡單嘗試一下。

1. 起因, 目的: agent mode, 很流行,名氣很大。簡單試試效果,確實很強。agent mode, 取代人工,確實是前進了一大步。 2. 先看效果 效果對比,左邊是 普通的AI 生成的, 右邊是 代理…

貝銳蒲公英工業路由器R300A海外版:支持多國4G頻段,全球組網

為更好地滿足全球部署和企業出海項目的多樣化需求,貝銳蒲公英異地組網工業路由器R300A海外版全新上市,并已正式上架速賣通!無論是跨國分支機構協同辦公,還是海外工廠設備遠程運維,R300A海外版都能為企業提供靈活、高性…

自然圖像數據集

目錄 CIFAR-10 數據集CIFAR-100 數據集AFHQ 數據集FFHQ 數據集 CIFAR-10 數據集 簡介: CIFAR-10 是一個經典的圖像分類數據集,廣泛用于機器學習領域的計算機視覺算法基準測試。它包含60000幅32x32的彩色圖像,分為10個類,每類6000…

【AI面試秘籍】| 第25期:RAG的關鍵痛點及解決方案深度解析

今天我們來聊聊大模型領域一個非常火熱的技術——RAG(Retrieval Augmented Generation)。RAG通過引入外部知識庫,有效地緩解了大型語言模型(LLM)在處理知識密集型任務時可能出現的幻覺、知識過時等問題。然而&#xff…

精英-探索雙群協同優化(Elite-Exploration Dual Swarm Cooperative Optimization, EEDSCO)

一種多群體智能優化算法,其核心思想是通過兩個分工明確的群體——精英群和探索群——協同工作,平衡算法的全局探索與局部開發能力,從而提高收斂精度并避免早熟收斂。 一 核心概念 在傳統優化算法(如粒子群優化、遺傳算法&#xf…

Transformer相關

問題匯總 Transformer的結構自注意力機制(Self-Attention)多頭自注意力前饋神經網絡(Feed-Forward Network, FFN)位置編碼編碼器(Encoder)和解碼器(Decoder)Multi-Query Attention(多查詢注意力機制)Grouped-query Attention(分組查詢注意力機制)FlashAttention與注…

【位運算】兩整數之和(medium)

兩整數之和(medium) 題?描述:解法(位運算):代碼復雜度分析 題?鏈接: 371. 兩整數之和 題?描述: 給你兩個整數 a 和 b ,不使? 運算符 和 - ,計算并返回兩…

現代密碼學入門 | 現代密碼學核心特點介紹

在當今互聯互通的世界中,數字數據在全球范圍內不斷流動,安全通信和數據保護的需求從未如此迫切。現代密碼學作為數字防御的先鋒,提供了一系列復雜的技術和算法,以保護信息免受窺探和惡意行為的侵害。 現代密碼學是從其古典前身—…

Redis分布式鎖深度解析與最佳實踐

1 2 Redis分布式鎖實現方式確實是經典問題,下面我將系統性地分析這個方案及其演進過程,并給出生產級的解決方案。 一、基礎方案及其缺陷 1. 初始實現方式 SETNX lock_key unique_value # 嘗試獲取鎖 EXPIRE lock_key 30 # 設置過期時間 …

Hive自定義函數案例(UDF、UDAF、UDTF)

目錄 前提條件 背景 概念及適用場景 UDF(User-Defined Function) 概念 適用場景 UDAF(User-Defined Aggregate Function) 概念 適用場景 UDTF(User-Defined Table-Generating Function) 概念 適…

Go語言的原子操作

當我們想要對某個變量并發安全的修改,除了使用官方提供的mutex,還可以使用sync/atomic包的原子操作,它能夠保證對變量的讀取或修改期間不被其他的協程所影響。 Golang提供的原子操作都是非侵入式的,由標準庫sync/atmoic包提供&am…

QNAP MEMOS 域名訪問 SSL(Lucky)

注意:下述是通過ssh、docker-compose方式安裝docker的,不是直接在container station中安裝的哈!!! 一、編輯docker-compose.yml文件 用“#”號標識的,在保存文件的時候建議去掉,不然有時候會出…

C#實現遠程鎖屏

前言 這是一次提前下班沒有鎖屏進而引發的一次思考后的產物,思考的主要場景是當人離開電腦后,怎么能控制電腦鎖屏,避免屏幕上的聊天記錄被曝光。 首先想到通過系統的電源計劃設置閑置超時時間熄屏,這可能是最接近場景的解決方案&a…

[Protobuf]常見數據類型以及使用注意事項

[Protobuf]常見數據類型以及使用注意事項 水墨不寫bug 文章目錄 一、基本數據類型1、字段2、字段的修飾規則 二、自定義數據類型1、message類型2、enum類型3、Any類型4、oneof類型5、map類型 三、小工具1.hexdump2.decode 四、注意事項 一、基本數據類型 protobuf 支持多種基礎…

JS分支和循環

程序的執行順序 在程序開發中&#xff0c;程序有三種不同的執行順序 1.順序執行 2.分支執行 3.循環執行 程序的代碼塊 <script>//一個代碼塊{var num11var num22var num3num1num2}//一個休想var info{name:"chen",age:18} 1.if分支語句&#xff08;單分支語句&…

Android 開發 Kotlin 全局大喇叭與廣播機制

在 Android 開發中&#xff0c;廣播機制就像一個神通廣大的 “消息快遞員”&#xff0c;承擔著在不同組件間傳遞信息的重任。Kotlin 語言的簡潔優雅更使其在廣播機制的應用中大放異彩。今天&#xff0c;就讓我們一同深入探索 Android 開發中 Kotlin 全局大喇叭與廣播機制的奧秘…

rabbitmq AI復習

RabbitMq rabbitmq &#x1f9d1;?&#x1f4bb; User 幫我復習rabbitmq相關知識&#xff0c;我是一個經驗豐富的程序員 &#x1f916; Assistant 好的&#xff01;很高興能通過這種方式幫你復習或學習 RabbitMQ 的知識。按照你說的流程&#xff0c;我們從完全零基礎開始&…