(重點) MySQL(入門篇16)事務,事務案例,事務隔離級別

目錄

在這裏插入圖片描述

一、事務

事務有ACDI原則

1.原子性(Atomicy)

要麼都成功,要麼都失敗

2. 一致性(Consistency)

事務前後的數據保持一致

3.持久性(Durability) – 事務提交

事務一旦提交不可逆

4.隔離性 (Isolation)

多個人,同時給張三轉錢的時候,每一筆轉賬開啓一個事務,多個事務相互隔離就是隔離性

二、隔離性產生的數據問題

多個用戶都在操作數據產生的數據問題。

1.髒讀 :一個事務讀取了了另一個事務沒有提交的 數據

1.比如張三和李四同時區銀行取相同賬號的錢,此時賬戶上有1000,李四,取錢1000,數據還沒有提交成功
2.張三以迅雷不及掩耳之勢迅速取錢 1000,此時因爲賬戶的數據還沒有來得及修改,於是,張三查詢餘額的時候還是1000.

2.不可重複讀:多次數據讀取的結果不同 (這個不一定是錯誤)

1.你查看 QQ 的信息,第一次刷新,沒有人給你發信息,第二次刷新,出現了一條信息,2次查詢的結果不一致,因爲第一次刷新的對方還沒有提交成功,就是不可重複讀

3.虛讀(幻讀):在一個事務內讀取到了別人插入的數據,導致前後不一致。

和不可重複讀類似,第一次查詢餘額的時候,是1000 元,然後別人充值了1000 元,你第二次查詢的時候就是 2000 元了,

三、事務4個隔離級別

1.四個隔離級別的瞭解

設置級別 髒讀 不可重複讀 幻讀
可讀未提交(read-uncommitted)
只讀提交(read-committed)
可重複讀(repeatable-read)
可序列化(serializable)

可見,可序列化 serializable,最安全但是速度最慢。

值得一提的是:大多數數據庫默認 read-committted 比如SQLServer 和Oracle,MySQL是更高級的 repeatable-read.

2.四個隔離級別詳解:

參考博客 https://blog.csdn.net/qq_33290787/article/details/51924963

2.1.可讀未提交 (read-uncommitted)

(1)意義:顧名思義,讀取的修改了(update)沒有提交(submit)的數據
(2)問題:會產生所有的隔離性數據問題
(3)舉例:張三,工資1萬元/月,但是,老闆給他發工資的時候不小心多輸入了一個0,10萬/月,此時update的SQL以及執行了,但是還沒有submit,張三早上查看自己的工資看到欣喜若狂,但是老闆發現自己輸入了一個0,連忙回滾(rollback),張三的工資又回到了設置之前,毫不知情的張三卻還樂呵呵的清空着他的購物車。這就是髒讀

2.2 只讀提交(read-committed)

(1)意義:就是隻能讀取提交後的數據,
(2)問題:解決髒讀的問題,但是其他問題依舊存在。
(3)舉例:

  • 1.解決髒讀問題:張三,工資1萬元/月,但是,老闆給他發工資的時候不小心多輸入了一個0,10萬/月,此時update的SQL以及執行了,但是還沒有submit,張三早上查看自己的工資還是以前的工資,應爲老闆還沒提交submit
  • 2.不可重複讀取的問題:張三和朋友聚餐,“服務員結賬!”張三招了招手,服務員唯唯諾諾過來,張三掏出手機看了看自己的餘額,1000元,“掃碼”,服務員趕緊立馬拿出了收款碼,張三對準二維碼正掃描着,(同時張三的女朋友用張三的銀行卡清空了自己1000元的的購物車,並付款支付成功)張三手機叮一聲,掃碼成功,一個圈圈轉啊轉,最後彈出一條提示,“您的餘額不足”,張三當時心態爆炸。這就是不可重複讀
2.3. 可重複讀(repeatable-read)

(1)意義:可以重複讀取的數據
(2)問題:在read-committed的基礎上解決update,更新數據產生的不可重複讀的問題,但是還有插入insert導致的幻讀的問題。
(3)舉例:

  • 1.解決不可重複讀的問題: 張三買單時(事務開啓,不允許其他事務驚醒update操作),同時張三的女朋友用張三的銀行卡清空自己1000元的的購物車,並付款**,無法進行update操作,付款失敗**。)張三消費成功。
  • 2.幻讀的問題:張三女友購物消費1000,然後她去查看自己的消費記錄(妻子事務開啓,掃描全表)正在查找的時候,張三消費1000元請朋友喫飯,(張三提交消費數據insert)此時妻子打印消費結果的時候發現多了一個1000元的消費,一共消費了2000元,似乎產生的幻覺,這就是幻讀,幻讀其實並不一定是錯誤。
2.4.序列化Serializable

(1)意義:參考幻讀的問題
(2)問題:解決所有數據讀取問題,但是因爲速度太低,一般不採用
(3)例子:參考幻讀的問題。

3.如何設置事務的隔離級別?

3,1 全局修改

在mysql.ini 配置文件最後加上

#可選的參數有: read-uncommitted ,read-committed ,repeatable-read,serializable
[mysqld]
transaction-isolation = REPEATABLE-READ
3.2 對當前session修改

登錄mysql之後,輸入

set session transaction isolation level read uncommitted; 

四、事務的案例模擬

1.建表

1.數據庫 事務銀行 tansactionBank

CREATE DATABASE IF NOT EXISTS `transactionBank`CHARACTER SET utf8 COLLATE utf8_general_ci;

2.表 事務銀行 tansactionBank01

CREATE TABLE IF NOT EXISTS `tansactionBank01`(
`id` INT NOT NULL AUTO_INCREMENT COMMENT "賬號",
`name` VARCHAR(30) NOT NULL COMMENT "名稱",
`money` DECIMAL(9,2) NOT NULL DEFAULT 0 COMMENT "賬戶餘額00.00格式默認爲0",
 PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET=utf8

3.插入數據:

INSERT INTO `tansactionbank01`
(`name`,`money`)
VALUES
("張三",0),
("李四",1000);

最終效果:
在這裏插入圖片描述

2. 瞭解事務的基本操作

操作 作用 解釋
set autocommit = 0; 關閉自動提交,mysql默認啓動自動提交 使用手動事務之前關閉自動提交事務
set autocommit = 1; 啓動功自動提交 使用手動提交事務之後開啓自動提交事務
start transaction; 開啓一個(組)事務
commit; 提交事務 持久性,提交之後不能回滾了
rollback; 回滾事務 回到最初的起點(有存檔的辦法可回到存檔點但是不常用瞭解即可.)

3. 事務實例:使用事務李四給張三轉賬 500元

-- 1. 關閉自動提交,方便手動提交
SET autocommit = 0;
-- 2.開啓一個(組)新的事務
START TRANSACTION;
-- 3.進行事務轉賬操作
UPDATE `tansactionbank01` SET 
`money` = `money`- 500
WHERE `name` = "李四";

UPDATE `tansactionbank01` SET 
`money` = `money`+ 500
WHERE `name` = "張三";
-- 4. 回滾
ROLLBACK;
-- 4.2 提交
COMMIT;
-- 4.3 提交後再回滾 (數據已經更改持久性,不能回滾成功)
COMMIT;
ROLLBACK;
-- 5.把自動提交恢復爲默認.
SET autocommit = 1;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章