day08-MySQL事務

来源:https://www.cnblogs.com/liyuelian/archive/2022/10/08/16770511.html
-Advertisement-
Play Games

MySQL事務 先來看一個例子 有一張balance表: 需求:將tom的100塊錢轉到King賬戶中 執行的操作是: update balance set money = money -100 where id = 100 update balance set money = money +100 ...


MySQL事務

先來看一個例子

有一張balance表:

image-20221008163214071

需求:將tom的100塊錢轉到King賬戶中

執行的操作是:

 update balance set money = money -100 where id = 100
 update balance set money = money +100 where id = 200

這時,如果第一條語句執行成功,但第二條語句執行失敗,就會出現問題。

這裡引出一個需求,將多個dml語句(update,insert,delete)當做一個整體,要麼全部成功,要麼全部失敗

--->使用事務來解決

1.什麼是事務

  • 什麼是事務

事務用於保證數據的一致性,它由一組相關的dml語句(update,insert,delete)組成,該組的dml語句要麼全部成功,要麼全部失敗。如:轉賬就要用事務來處理,用以保證數據的一致性。

  • 事務和鎖

當執行事務操作時(dml語句),mysql會在表上加鎖,防止其他用戶修改表的數據。這對用戶來講是非常重要的。

  • mysql資料庫控制台事務的幾個重要操作(基本操作)
image-20221008170020052

註意:當直接回退到保存點a時,會刪除中間的保存點b

1.start transaction --開始一個事務
2.savepoint 保存點名 -- 設置保存點
3.rollback to 保存點名 -- 回退事務
4.rollback -- 回退全部事務
5.commit -- 提交事務,所有的操作生效,不能回退

細節:

  1. 沒有設置保存點
  2. 多個保存點
  3. 存儲引擎
  4. 開始事務方式
  • 回退事務

在介紹回退事務前,先介紹一下保存點(savepoint)。保存點是事務中的點,用於取消部分事務,當結束事務時(commit),會自動地刪除該事務所定義的所有保存點。

當執行回退事務時,通過指定保存點可以回退到指定的點

  • 提交事務

使用commit語句可以提交事務。當執行了commit語句之後,會確認事務的變化、結束事務、刪除保存點、釋放鎖,數據生效。

當使用了commit語句結束事務之後,其它會話[其他連接] 可以查看到事務變化後的新數據 [所有的數據正式生效]

例子

-- 事務的演示操作
-- 1.創建一張測試表
CREATE TABLE t27(
	id INT ,
	`name` VARCHAR(32)
);

SELECT * FROM t27;
-- 2.開始事務
START TRANSACTION;

-- 3.設置保存點
SAVEPOINT a;

-- 4.執行dml操作1
INSERT INTO t27 VALUES(100,'tom');

-- 設置保存點b
SAVEPOINT b;

-- 執行dml操作2
INSERT INTO t27 VALUES(200,'jack');

-- 回退到b
ROLLBACK TO b

-- 繼續回退a
ROLLBACK TO a

-- 如果是rollback,表示直接回退到事務開始的狀態
ROLLBACK

COMMIT

2.事務註意事項

  1. 如果不開始事務,預設情況下,dml操作是自動提交的,不能回滾
  2. 如果開始一個事務,你沒有創建保存點,也可以執行rollback,預設就是回到事務開始的狀態
  3. 可以在事務中(還沒有提交時),創建多個保存點。比如:savepoint aaa;執行dml,savepoint bbb;
  4. 可以在事務沒有提交前,選擇回退到哪個保存點
  5. innodb的存儲引擎支持事務,myisam不支持
  6. 開始一個事務的方式 start transaction或者set autocommit = off;

例子

-- 討論事務細節
-- 1. 如果不開始事務,預設情況下,dml操作是自動提交的,不能回滾
INSERT INTO t27 VALUES(300,'milan'); -- 自動提交 commit
SELECT * FROM t27;

-- 2. 如果開始一個事務,你沒有創建保存點,也可以執行rollback,
-- 預設就是回到事務開始的狀態
START TRANSACTION
INSERT INTO t27 VALUES(400,'king');
INSERT INTO t27 VALUES(500,'scott');
ROLLBACK -- 表示直接回退到事務開始的狀態
COMMIT
-- 3. 可以在事務中(還沒有提交時),創建多個保存點。
-- 比如:savepoint aaa;執行dml,savepoint bbb;
-- 4. 可以在事務沒有提交前,選擇回退到哪個保存點
-- 5. innodb的存儲引擎支持事務,myisam不支持

-- 6. 開始一個事務的方式 start transaction或者set autocommit = off;
SET autocommit = off

3.事務的四種隔離級別

  • 事務隔離級別介紹
  1. 多個連接開啟各自的事務,操作資料庫中的數據時,資料庫系統要負責隔離操作,以保證各個連接在獲取數據時的準確性。
  2. 如果不考慮隔離性,可能會引發如下問題:
    • 臟讀(dirty read):當一個事務讀取另一個事務尚未提交的改變(delete,insert,update)時,產生臟讀
    • 不可重覆讀(nonrepeatable read):同一個查詢在同一事務中多次進行,由於其他已提交事務所做的修改或刪除,每次返回不同的結果集,此時發生不可重覆讀
    • 幻讀(phantom read):虛讀,同一查詢在同一事務中多次進行,由於其他已提交事務所做的插入操作,每次返回不同的結果集,此時發生幻讀
  • 事務隔離級別

概念:MySQL隔離級別定義了事務與事務之間的隔離程度

MySQL隔離級別(4種) 臟讀 不可重覆讀 幻讀 加鎖讀
讀未提交(read uncommitted) 會出現 會出現 會出現 不加鎖
讀已提交(read committed) 不會出現 會出現 會出現 不加鎖
可重覆讀(repeatable read) 不會出現 不會出現 不會出現 不加鎖
可串列化(serializable) 不會出現 不會出現 不會出現 加鎖

可重覆讀實際上會發生幻讀?

3.1讀未提交(read uncommitted)

MySQL的事務隔離級別--案例

我們舉例一個案例來說明mysql的事務隔離級別。以account表進行操作為例。(id、name、money)

image-20221008192142902
  1. 開啟兩個mysql的控制台

  2. 查看當前mysql的隔離級別,均為可重覆讀

    mysql> select @@tx_isolation;
    +-----------------+
    | @@tx_isolation  |
    +-----------------+
    | REPEATABLE-READ |
    +-----------------+
    1 row in set (0.00 sec)
    
    image-20221008192933956
  3. 將其中一個連接的隔離級別設置為 read uncommitted(讀未提交)

    -- 把其中一個控制台的隔離級別設置為read uncommitted
    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    
    image-20221008193410009

    此時的情況:左邊的隔離級別為讀未提交;右邊的隔離級別為可重覆讀

    image-20221008193559255
  4. 然後兩邊都開啟事務

    image-20221008193914876
  5. 在兩個連接控制臺中選擇資料庫,在隔離級別為 可重覆讀 的連接中 創建表account

    image-20221008194826475
  6. 再在隔離級別為 可重覆讀 的連接中插入一條數據(但未提交)

    image-20221008195219059

    在另一個連接(隔離級別為 讀未提交 READ-UNCOMMITTED)中查詢該表,發現可以查詢到另一事務尚未提交的插入的數據,這時就發生了臟讀

    臟讀:當一個事務讀取另一個事務尚未提交的改變(delete,insert,update)時,產生臟讀

    image-20221008195640875
  7. 在隔離級別為 可重覆讀 的連接中更新一條數據,同時插入一條數據,然後提交commit

    image-20221008201529967

    此時在另一個連接(隔離級別為 讀未提交)中,查詢同一張表,可以看到在這個(隔離級別為 讀未提交的)連接中,已經可以看到另一個事務中提交的數據

    即一個事務的操作影響了另一個事務的查詢,這時候就發生了不可重覆讀和幻讀

    這將會導致,當有多個連接開啟事務時,某一連接的事務的查詢會受到其他所有連接的事務的影響,這無疑將會導致混亂

    最佳情況應該是:一個連接 連接到資料庫,操作account表的時候,希望看到的數據應該是,開啟事務的這一時刻的數據

    image-20221008201046545
  8. 在連接(隔離級別為 讀未提交)中提交commit結束一個事務,此時兩個連接中的事務均已結束

3.2讀已提交(read committed)

例子

  1. 在上個例子開啟的兩個連接中,將其中一個連接的隔離級別修改為 讀已提交,

    image-20221008204600469

    另一個保持隔離級別為可重覆讀

    image-20221008204315773
  2. 兩邊都開啟事務

    image-20221008204843656
  3. 在隔離級別為可重覆讀的連接中插入一條數據

    image-20221008205126687

    然後在隔離級別為讀已提交的連接中 插詢表account,可以看到查詢到的數據還是本連接開啟事務時的數據

    即,讀已提交的隔離級別不會出現臟讀現象

    image-20221008205446587
  4. 在隔離級別為可重覆讀的連接中更新一條數據

    image-20221008205758627

    然後在隔離級別為讀已提交的連接中 插詢表account,可以看到查詢到的數據變成了其他連接的事務提交的 數據,說明,在隔離級別為讀已提交下,出現了不可重覆讀和幻讀

    image-20221008205922194

3.3可重覆讀(repeatable read)

  1. 重新開啟兩個連接,兩個連接的隔離級別均為可重覆讀

    image-20221008211012203
  2. 然後兩邊均開啟事務

    image-20221008211323511
  3. 在一個連接中選擇資料庫,然後在account表中插入一條數據,再更新一條數據(未提交)

    image-20221008211905315

    此時該連接中的表情況為:

    image-20221008212031986

    在另一個連接中選擇資料庫,查詢表account,可以看到查詢到的表數據依舊是開啟事務時的樣子,沒有受到其他事務的影響,即沒有產生臟讀

    image-20221008212349587
  4. 在原先修改數據的連接中輸入commit提交

    image-20221008212643521

    在另一個連接中再查詢表account,可以看到數據依舊是開啟事務的時刻的樣子

    即,沒有產生不可重覆讀和幻讀

    image-20221008212835739

綜上,隔離級別為可重覆讀的情況下 既不會出現臟讀,也不會出現不可重覆讀和幻讀

3.4可串列化(serializable)

  1. 將上面兩個連接其中一個重新啟動,將新連接設置隔離級別為可串列化(serializable)

    image-20221008214024909

    此時兩個連接的隔離級別分別為 可重覆讀 和可串列化(serializable)

    image-20221008214313366
  2. 這時分別在兩個連接中均開啟事務

    image-20221008214528324
  3. 在隔離級別為可重覆讀的連接中分別插入、更新數據(未提交)

    image-20221008214720377

    ​ 在另一個隔離級別為可串列化的連接中選擇資料庫。然後查詢表account,回車時會發現卡住了,這是因為 可串列化會加鎖

    A連接在操作表的時候,事務還沒有結束,這時B連接也嘗試操作該表,此時將會檢查A的事務有沒有結束,如果沒有結束,B連接的操作就會進行等待,直到A連接的事務提交

    image-20221008215219456

    ​ 這時,在隔離級別為可重覆讀的連接中提交事務

    image-20221008215348752

    ​ 可以看到可串列化級別的連接中可以成功操作表了

    image-20221008220238356

綜上說明,可串列化級別下,不僅不會出現臟讀、不可重覆讀、幻讀,還會加鎖讀

4.設置隔離


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .NET下資料庫的負載均衡(有趣實驗)這篇文章發表後,受到了眾多讀者的關註與好評,其中不乏元老級程式員。 讀者來信中詢問最多的一個問題是:它是否能支持“異種資料庫”的負載均衡?? 今天就在此統一回覆:能(暫時只能在.Net6版本下實現。.Net Framwork版本後續會再實現。) 下麵就通過一個例 ...
  • 一:背景 1.講故事 最近遇到一位朋友的程式崩潰,發現崩潰點在富編輯器 msftedit 上,這個不是重點,重點在於發現他已經開啟了 頁堆 ,看樣子是做了最後的掙扎。 0:000> !analyze -v EXCEPTION_RECORD: (.exr -1) ExceptionAddress: 8 ...
  • 一、keepalived是什麼 Keepalived 軟體起初是專為LVS負載均衡軟體設計的,用來管理並監控LVS集群系統中各個服務節點的狀態,後來又加入了可以實現高可用的VRRP功能。因此,Keepalived除了能夠管理LVS軟體外,還可以作為其他服務(例如:Nginx、Haproxy、MySQ ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是一種靈活的i.MXRT下多串列NOR Flash型號選擇的量產方案。 對於以 i.MXRT 這類沒有內部 NVM (Non-Volatile Memory) 的 MCU 為主控的項目來說,為其選配一顆 NVM 作為代碼存儲器是頭等大事, ...
  • 如何設計藝術字?如何進行圖標設計?Art Text 4 Mac版是一款藝術字體製作和圖標設計軟體,它支持多圖層,可以輕鬆創造複雜圖形。可將該程式創建的圖形應用於iWork,Microsoft office、BeLight等應用程式,以及各種其他文本編輯和網頁設計程式。使用Art Text 4 Mac ...
  • @(文章目錄) 前言 上一篇和大家一起分享瞭如何使用LabVIEW OpenCV dnn實現手寫數字識別,今天我們一起來看一下如何使用LabVIEW OpenCV dnn實現圖像分類。 一、什麼是圖像分類? 1、圖像分類的概念 圖像分類,核心是從給定的分類集合中給圖像分配一個標簽的任務。實際上,這意 ...
  • 還在尋找一款好玩的休閑益智游戲嗎?現為大家分享一款經典割繩子游戲Cut the Rope Remastered Mac版,這款游戲的目標很簡單,就是合理的切割繩子,讓小怪物吃到糖果即可過關,但是要想得到高評價,就要想辦法吃到所有的星星。 詳情:經典割繩子游戲Cut the Rope Remaster ...
  • 作者:小牛呼嚕嚕 | https://xiaoniuhululu.com 電腦內功、JAVA底層、面試相關資料等更多精彩文章在公眾號「小牛呼嚕嚕 」 什麼是CPU上下文 Linux是一個多任務的操作系統,多任務操作系統是指多個進程運行在一個 CPU 中互不打擾,看起來像同時運行一樣。多任務的操作系 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...