40.MySQL事務

1.事務的作用

事務用于保證數據的一致性,它由一組相關的 dml (update delete insert) 語句組成,該組的 dml (update delete insert) 語句要么全部成功,要么全部失敗

如:轉賬就要用事務來處理,用以保證數據的一致性。

假設張三給李四轉100塊:

銀行后臺有一張簡單的數據庫余額表:

為了完成轉賬這件事,銀行后臺需要執行這兩條sql語句:

這時候就會出現三種情況:

1.第一條語句執行失敗,第二條語句執行成功,結果出錯;

2.第一條語句執行成功,第二條語句執行失敗,結果出錯;

3.兩條語句全部執行失敗;

4.兩條語句全部執行成功;

假如你是銀行的話,當然會希望這兩條語句要么同時失敗,要么同時成功。

這就引出我們的需求:兩個sql語句作為一個整體,用以保證數據的一致性。

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

2.事務的操作

2.1開始一個事務

基本語法:

start transaction; -- 開始一個事務

2.2設置保存點

保存點 (savepoint), 保存點是事務中的點,用于取消部分事務,當結束事務時(commit),會自動的刪除該事務所定義的所有保存點。

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

基本語法:

savepoint 保存點名; -- 設置保存點

2.3回退事務

基本語法:

rollback to 保存點名; -- 回退事務

2.4回退全部事務

基本語法:

rollback; -- 回退全部事務

2.5提交事務

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

當使用 commit 語句結束事務子后,其它會話【其他用戶的連接】將可以查看到事務變化后的新數據。

類似于下圖。而讓用戶2在用戶1開始事務時對用戶1的操作的數據不可見的功能就叫做隔離

基本語法:

commit; -- 提交事務,所有的操作生效,不能回退

2.6示例

先創建一個簡單的表:

CREATE TABLE t03 (id INT,`name` VARCHAR(32)
);

開啟一個事務:

START TRANSACTION;

插入一條數據:

insert into t03 values(1,'tom');

設置一個保存點:

savepoint a;

再次插入一條數據:

insert into t03 values(2,'Jack');

再設置一個保存點:

savepoint b;

再次插入一條數據:

insert into t03 values(3,'lucy');

回滾到保存點a:

ROLLBACK TO a;

回滾全部:回到了最開始剛開啟事務時的樣子。

ROLLBACK;

再次插入一條數據:

insert into t01 values(4,'jep');

提交事務:

COMMIT;

再次回滾全部:

ROLLBACK;

數據已經生效,保存點全部被刪除,回滾不了了。

3.事務的使用細節

3.1 沒有設置保存點

如果不開始事務,默認情況下,dml 操作是自動提交的,不能回滾。

如果開始一個事務,你沒有創建保存點。你可以執行 rollback,默認就是回退到你事務開始的狀態.

3.2 多個保存點

你也可以在這個事務中 (還沒有提交時), 創建多個保存點。

比如:

savepoint aaa;

執行 dml;

savepoint bbb;

你可以在事務沒有提交前,選擇回退到哪個保存點。

3.3 存儲引擎

mysql 的事務機制需要 innodb 的存儲引擎才可以使用,myisam 不好使。

3.4 開始事務方式

開始一個事務有兩種方式:

start transaction;
set autocommit=off;

4.四種隔離級別

4.1隔離的基本介紹

事務隔離級別介紹:

  1. 多個連接開啟各自事務操作數據庫中數據時,數據庫系統要負責隔離操作,以保證各個連接在獲取數據時的準確性。(通俗解釋)
  2. 如果不考慮隔離性,可能會引發如下問題:
    ? 臟讀
    ? 不可重復讀
    ? 幻讀

舉個例子:當MySQL同時又兩個連接C1,C2

C1在對這個表進行dml操作的時候,C2再查詢這張表的時候所看到的是怎樣的一種數據,取決于C2的隔離級別。

4.2不做隔離引發的問題

①臟讀(dirty read):

當一個事務讀取另一個事務尚未提交修改時,產生臟讀。


②不可重復讀(nonrepeatable read):

同一查詢在同一事務中多次進行,由于其他提交事務所做的修改或刪除,每次返回不同的結果集,此時發生不可重復讀。


③幻讀(phantom read):

同一查詢在同一事務中多次進行,由于其他提交事務所做的插入操作,每次返回不同的結果集,此時發生幻讀。

4.3事務隔離級別

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

Mysql隔離級別(4種)

臟讀

不可重復讀

幻讀

加鎖讀

加鎖寫

讀未提交(Read uncommitted)

V

V

V

不加鎖

加鎖(排他鎖)

讀已提交(Read committed)

x

V

V

不加鎖

加鎖(排他鎖)

可重復讀(Repeatable read)

x

x

x

不加鎖

加鎖(排他鎖 + 間隙鎖 / 臨鍵鎖)

可串行化(Serializable)

x

x

x

加鎖

加鎖(排他鎖)

說明:V 可能出現 ×不會出現

4.4事務隔離級別的特性

mysql事務ACID

  • 事務的acid特性
    1. 原子性(Atomicity)
      原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發生,要么都不發生。
    2. 一致性(Consistency)
      事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。
    3. 隔離性(Isolation)
      事務的隔離性是多個用戶并發訪問數據庫時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作數據所干擾,多個并發事務之間要相互隔離。
    4. 持久性(Durability)
      持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響。

4.5事務隔離級別的設置與查看

mysql事務隔離級別

  1. 查看當前會話隔離級別(用戶臨時登錄時的隔離級別)
select @@tx_isolation;  
  1. 查看系統當前隔離級別(所有用戶登錄時默認的隔離級別)
select @@global.tx_isolation;  
  1. 設置當前會話隔離級別
set session transaction isolation level [Read uncommitted/Read committed/repeatable read/Serializable]; 
  1. 設置系統當前隔離級別
set global transaction isolation level [Read uncommitted/Read committed/repeatable read/Serializable];  
  1. mysql 默認的事務隔離級別是 repeatable read ,一般情況下,沒有特殊要求,沒有必要修改(因為該級別可以滿足絕大部分項目需求)

真的想改mysql系統默認隔離級別的話:

全局修改,修改 mysql.ini 配置文件,在最后加上transaction-isolation = REPEATABLE-READ
--可選參數有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.

之后重啟mysql服務,就完成了修改。

4.6事務隔離級別的演示

①讀未提交

左右都開一個mysql的連接,左邊我們取做連接1,右邊取做連接2;

選取一個數據庫:

use mysql_learn;

在該數據庫下創建一個表:

create table account (id int,name varchar(32),money int);

查看一下兩邊的事務隔離級別:

select @@tx_isolation;

連接1的為REPEATABLE-READ(可重復讀),也就是mysql默認的事務隔離級別;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+

連接2的設置為讀未提交:

set session transaction isolation level Read uncommitted;

再次查看一下連接2的隔離級別為READ-UNCOMMITTED(讀未提交):

select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+

現在我們在兩個連接上同時開啟事務:

連接2的事務中查看一下該表:

我們在連接1執行幾條dml語句:

insert into account values(100,'tom',3000);
insert into account values(200,'jack',5000);
update account set money = money + 100 where id = 100;

注意!我們連接1和連接2的事務都是沒有提交的,但是此刻在連接2查看一下這張表:

連接1提交一下事務,再在連接2查看一下這張表:

在并行的連接1和連接2中的事務中,我們會發現,在連接2中還未提交的事務中多次查看account表的結果會由于連接1中的事務中的dml操作以及事務的提交而變化。

這也就是“讀未提交”這個隔離級別可能會造成贓讀,不可重復讀,幻讀等問題。

②讀已提交

將連接2的事務也提交一下(其實什么都沒做,只是演示);

現在將連接2的隔離級別設置為:Read committed(讀已提交);

 set session transaction isolation level Read committed;

現在,將連接1和連接2中同時開啟事務:

連接2的事務中查看一下該表:

在連接1的事務中執行幾句dml:

insert into account values(300,'lucy',9999);
insert into account values(400,'chen',10000);
update account set money = money + 10000 where id = 300;

注意!此刻連接1和2的事務都是沒有提交的,我們在連接2的事務中查看一下該表:

可以發現,連接1未提交的事務中做的修改,沒有在連接2的事務中查看到;

將連接1的事務提交一下,再在沒有提交的連接2開啟的事務中查看該表:

在并行的連接1和連接2中的事務中,可以發現在沒有提交的連接2開啟的事務當中,對account表的查看結果受到了連接1中的含有dml操作的事務的提交而改變。

在“讀已提交”的隔離級別下,可能會引起不可重復讀以及幻讀問題。

③可重復讀

將連接2的事務提交一下,并且將其隔離級別設置為Repeatable read(可重復讀):

commit;
set session transaction isolation level repeatable read; 

連接1和連接2再次開啟事務:

連接2的事務中查看一下該表:

在連接1的事務中執行幾句dml:

insert into account values(500,'kimi',8888);
insert into account values(600,'liu',20000);
update account set money = money - 1000 where id = 500;

注意!此刻連接1和2的事務都是沒有提交的,我們在連接2的事務中查看一下該表:

可以發現,連接1未提交的事務中做的修改,沒有在連接2的事務中查看到;

將連接1的事務提交一下,再在沒有提交的連接2開啟的事務中查看該表:

在并行的連接1和連接2中的事務中,可以發現在沒有提交的連接2開啟的事務當中對account表的多次查看結果并沒有受到已經提交了的連接1開啟的事務的dml操作以及提交而改變。

也就是說可重復讀這個隔離級別不會有贓讀,不可重復讀以及幻讀等問題。

④可串行化

將連接2的事務提交一下,并且將其隔離級別設置為:Serializable(可串行化);

commit;
set session transaction isolation level Serializable; 

連接1和連接2再次開啟事務:

連接2的事務中查看一下該表:

在連接1的事務中執行幾句dml:

insert into account values(700,'chuyi',22222);
insert into account values(800,'shiwu',33333);
update account set money = money + 11111 where id = 700;

注意!此刻連接1和2的事務都是沒有提交的,我們在連接2的事務中查看一下該表:

會發現回車鍵輸入無效,連接2的事務中查看不了正在被連接1事務操作的account這張表!

這就說明account這張表對于隔離級別為“可串行化”的連接2開啟的事務來說是被上了鎖的。

我們將連接1的事務提交一下:

再在沒有提交的連接2開啟的事務中查看該表:

在實際上并行的連接1和連接2中的事務中,由于可串行化的隔離級別的加鎖機制,使得連接1和連接2中的事務得到了形式上串行的效果,并且也達到了數據同步得效果。

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

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

相關文章

java導入pdf(攜帶動態表格,圖片,純java不需要模板)

java導出pdf文件一、介紹二、準備三、實現效果四、代碼一、介紹 上一篇文章(java使用freemarker操作word(攜帶動態表格,圖片))https://blog.csdn.net/weixin_45853881/article/details/129298494 緊跟上文&#xff0c…

【dropdown組件填坑指南】鼠標從觸發元素到下拉框中間間隙時,下拉框消失,怎么解決?

開發dropdown組件填坑之hideDelay 引言 在開發下拉菜單(dropdown)或彈出框(popover)組件時,一個常見的用戶體驗問題就是鼠標移出觸發區域后,彈出內容立即消失,這會導致用戶無法移動到彈出內容上…

Linux I/O 函數完整清單

Linux I/O 函數完整清單 1. 基礎 I/O 函數 1.1 基本讀寫 #include <unistd.h>ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);1.2 位置指定讀寫 #include <unistd.h>ssize_t pread(int fd, void *buf, siz…

面經——電子電路技術知識詳解

電子電路技術知識詳解 目錄 德摩根定律周期性矩形波產生方法自激振蕩器原理與設計晶體管溫度效應分析反向飽和電流影響因素放大電路負反饋類型判斷正弦波90相移電路直接耦合放大器的缺點二階有源低通濾波器分析開關電源與線性電源對比 德摩根定律 德摩根定律&#xff08;De …

docker 安裝 gitlab

null文章瀏覽閱讀445次。問題&#xff1a;運行 docker run hello-world 報錯。原因&#xff1a;原鏡像源網絡不穩定。https://blog.csdn.net/sszdzq/article/details/145733419 鏡像獲取 在線下載 docker pull gitlab/gitlab-ce:17.11.1-ce.0 離線獲取 創建運行 sudo docke…

PHP中的日期/時間處理之Carbon組件

日常開發中&#xff0c;我們會經常用到日期和時間的操作&#xff0c;但官方的一般操作比較復雜&#xff0c;需要大量的時間進行格式化問題和大量計算等等。Carbon組件 可以幫助我們在 PHP 開發中處理日期/時間變得更加簡單、更語義化&#xff0c;從而使得我們的代碼更容易閱讀和…

學習嵌入式第十八天

文章目錄1.數據結構1.概念2.衡量代碼質量和效率1.時間復雜度2.空間復雜度3.數據結構分類1.邏輯結構2.存儲結構3.常見的數據結構2.鏈表1.與順序表的區別2.鏈表分類1.單向鏈表1.定義鏈表節點類型2.空鏈表的創建3.鏈表的頭插法4.鏈表的遍歷5.鏈表元素刪除3.makefile習題1.數據結構…

基于SpringBoot+Vue實現校園商鋪系統

作者主頁&#xff1a;編程指南針 作者簡介&#xff1a;Java領域優質創作者、CSDN博客專家 、CSDN內容合伙人、掘金特邀作者、阿里云博客專家、51CTO特邀作者、多年架構師設計經驗、多年校企合作經驗&#xff0c;被多個學校常年聘為校外企業導師&#xff0c;指導學生畢業設計并參…

從資源閑置到彈性高吞吐,JuiceFS 如何構建 70GB/s 吞吐的緩存池?

AI 模型的訓練與推理對存儲系統提出了極為嚴苛的要求&#xff0c;特別是在高吞吐、高并發以及對海量小文件的高效處理方面&#xff0c;已成為三大主要挑戰。盡管基于 Lustre 或 GPFS 的并行文件系統具備出色的性能&#xff0c;但其成本高昂、吞吐能力與容量強耦合&#xff0c;可…

提升JVM性能之CMS垃圾回收器的優化分析與案例剖析

這里寫目錄標題一、CMS基本介紹二、CMS核心優化策略1. 避免并發模式失敗&#xff08;Concurrent Mode Failure&#xff09;2. 減少內存碎片3. 調優并發階段耗時4. 新生代優化配合三、典型案例解析案例1&#xff1a;電商服務頻繁Full GC案例2&#xff1a;金融交易系統碎片導致長…

Token系列 - 再談穩定幣

相關政策 2024年12月&#xff0c;歐洲《加密資產市場監管法案》正式成為法律2025年3月&#xff0c;日本細化了加密資產及穩定幣的監管調整2025年5月&#xff0c;英國發布了關于穩定幣發行、加密資產托管及加密資產公司財務穩健性的監管提案&#xff1b;2025年5月20日&#xff…

【20min 急速入門】使用Demucs進行音軌分離

創建環境 conda create --name mujica python3.10下載加速依賴 先用nvidia-smi檢查機器使用的獨顯版本, 然后從pytorch官網下載對應的GPU版torch, torchaudio 比如我的是12.2, 就下載11.8版本的 pip3 install torch torchvision torchaudio --index-url https://download.p…

字節Seed發布擴散語言模型,推理速度達2146 tokens/s,比同規模自回歸快5.4倍

用擴散模型寫代碼&#xff0c;不僅像開了倍速&#xff0c;改起來還特別靈活&#xff01;字節Seed最新發布擴散語言模型Seed Diffusion Preview&#xff0c;這款模型主要聚焦于代碼生成領域&#xff0c;它的特別之處在于采用了離散狀態擴散技術&#xff0c;在推理速度上表現出色…

海洋大地測量基準與水下導航系列之九我國海洋PNT最新技術進展(下)

三、海洋PNT技術裝備研發與工程化應用 1.海底基準裝備 研制了首批適應海洋環境的多型海底基準站裝備&#xff0c;在我國南海海域成功布設了定位精度優于0.25m的海底大地測量試驗基準網&#xff0c;實現了我國海底大地測量基準技術零的突破。基準方艙具備穩固、抗壓、防腐、防…

入門MicroPython+ESP32:安裝逗腦IDE及驅動

本篇文章將手把手帶大家入門MicroPython ESP32&#xff0c;重點介紹逗腦IDE的安裝過程以及相關驅動的安裝。 一、下載逗腦IDE 要開始使用逗腦IDE&#xff0c;首先需要從官網下載最新版本。請訪問以下網址進行下載&#xff1a;https://www.itprojects.cn/ide 下載時的界面大…

CentOS上部署Redis及其哨兵(Sentinel)模式

架構&#xff1a;說明我這里是偽集群的&#xff0c;redis 在同一臺機器&#xff0c;Sentinel 只有一個&#xff0c;也存在單點故障問題只能當作開發環境使用&#xff0c;要滿足生產至少是下面這種架構 ------------------- ------------------- ------------------- …

《軟件測試與質量控制》實驗報告二 單元測試

目 錄 一、實驗學時 二、實驗目的 三、實驗環境 &#xff08;一&#xff09;硬件環境&#xff1a; &#xff08;二&#xff09;軟件環境&#xff1a; 四、實驗內容 1、實驗方案&#xff1a; 2、實驗步驟&#xff1a; 3、設計思路&#xff1a; 1、安裝JUnit和Eclemma…

k8s模式部署PolarDB-X

當前文檔適配PolarDB-X V2.4.0 版本 環境描述&#xff1a; 部署機&#xff08;ops&#xff09;1x2.2x.2x8.116&#xff0c;部署機需要可以訪問互聯網。使用ansible進行部署&#xff0c;自行安裝ansible。需要部署兩個k8s集群&#xff0c;分別在其上安裝一個polardb-x集群。 部…

Flask + YARA-Python*實現文件掃描功能

以下是一個 完整的 Web API 示例&#xff0c;使用 Flask YARA-Python 實現文件掃描功能&#xff0c;支持上傳文件并返回 YARA 規則匹配結果。 ? 功能說明 提供一個 /scan 接口&#xff0c;支持文件上傳使用預加載的 YARA 規則進行掃描返回 JSON 格式的匹配結果支持多規則、可…

WinForm之NumericUpDown控件

NumericUpDown&#xff08;數字上下控件&#xff09;是 WinForm 中專門用于輸入和調整數值的控件&#xff0c;它結合了文本框和上下按鈕&#xff0c;用戶可通過點擊按鈕或直接輸入來設置數值&#xff0c;且能嚴格限制數值范圍&#xff08;最小值、最大值&#xff09;和步長&…