最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql數(shù)據(jù)庫(kù)事務(wù)的臟讀幻讀及不可重復(fù)讀詳解

 更新時(shí)間:2022年05月30日 09:59:18   作者:把蘋(píng)果咬哭的測(cè)試筆記  
這篇文章主要為大家介紹了Mysql數(shù)據(jù)庫(kù)事務(wù)的臟讀幻讀及不可重復(fù)讀詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、什么是數(shù)據(jù)庫(kù)事務(wù)

數(shù)據(jù)庫(kù)事務(wù)( transaction)是訪問(wèn)并可能操作各種數(shù)據(jù)項(xiàng)的一個(gè)數(shù)據(jù)庫(kù)操作序列,這些操作要么全部執(zhí)行,要么全部不執(zhí)行,是一個(gè)不可分割的工作單位。事務(wù)由事務(wù)開(kāi)始與事務(wù)結(jié)束之間執(zhí)行的全部數(shù)據(jù)庫(kù)操作組成。——百度百科

比如,你有2條sql要執(zhí)行,如果放到一個(gè)事務(wù)里,要么2個(gè)sql都執(zhí)行成功,要么都失敗。都執(zhí)行成功了就提交事務(wù),有一個(gè)失敗了就回滾,不存在一個(gè)成功一個(gè)失敗。

二、事務(wù)的ACID原則

這是數(shù)據(jù)庫(kù)事務(wù)的核心所在。

1. 原子性(Atomicity)

比如現(xiàn)在A有800元,B有200元,A給B轉(zhuǎn)賬200元。完成此場(chǎng)景有2步,可以當(dāng)做在一個(gè)事務(wù)里:

1- A:800-200=600
2- B:200+200=400

那么,這2個(gè)步驟只能都成功,或者都失敗。如果一個(gè)成功一個(gè)失敗了,那么有一個(gè)人的錢(qián)就不對(duì)了。原子性就是表示不能只發(fā)生其中一個(gè)動(dòng)作。

2. 一致性(Consistency)

針對(duì)一個(gè)事務(wù)操作前與操作后的狀態(tài)一致。

比如現(xiàn)在A有800元,B有200元,2個(gè)人總計(jì)是1000元。那么不管這2個(gè)人之間怎么轉(zhuǎn)來(lái)轉(zhuǎn)去,總和一定還是1000元,錢(qián)不會(huì)憑空產(chǎn)生或消失。

3. 持久性(Durability)

對(duì)于任意已提交事務(wù),系統(tǒng)必須保證該事務(wù)對(duì)數(shù)據(jù)庫(kù)的改變不被丟失,即使數(shù)據(jù)庫(kù)出現(xiàn)故障。

比如現(xiàn)在A有800元,B有200元,此時(shí)A要給B轉(zhuǎn)賬200,或有2種情況:

1. 事務(wù)還沒(méi)提交,這時(shí)候服務(wù)掛了或者斷電,那么重啟數(shù)據(jù)庫(kù)后,數(shù)據(jù)狀態(tài)應(yīng)該為:A有800元,B有200元

2. 事務(wù)已經(jīng)提交,這時(shí)候服務(wù)掛了或者斷電,那么重啟數(shù)據(jù)庫(kù)后,數(shù)據(jù)狀態(tài)應(yīng)該為:A有600元,B有400元

可以看到,事務(wù)一旦提交,就會(huì)持久化到數(shù)據(jù)庫(kù)里,不會(huì)因外界原因?qū)е聰?shù)據(jù)丟失。

4. 隔離性(Isolation)

事務(wù)的執(zhí)行不受其他事務(wù)的干擾,事務(wù)執(zhí)行的中間結(jié)果對(duì)其他事務(wù)必須是透明的。

比如現(xiàn)在有2個(gè)事務(wù)同時(shí)進(jìn)行,A和C同時(shí)在給B轉(zhuǎn)賬:

事務(wù)一:A有800元,B有200元,A給B轉(zhuǎn)賬200元

事務(wù)二:C有1000元,B有200元,C給B轉(zhuǎn)賬100元

這2個(gè)事務(wù)不會(huì)互相影響。隔離性就是針對(duì)多用戶同時(shí)操作的情況下,排除其他事務(wù)對(duì)本事務(wù)的影響。

三、隔離帶來(lái)的問(wèn)題

數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別有4個(gè),強(qiáng)度從低到高依次為:
Read uncommitted 、Read committed 、Repeatable read、Serializable,而隨著隔離級(jí)別的不同,會(huì)引發(fā)一些其他的問(wèn)題。

1. 臟讀

一個(gè)事務(wù)讀取了另外一個(gè)事務(wù)未提交的數(shù)據(jù),就是臟讀。

事務(wù)1: A給B轉(zhuǎn)賬500,但是事務(wù)未提交。

事務(wù)2: B查看了賬戶,發(fā)現(xiàn)A轉(zhuǎn)過(guò)來(lái)500,本來(lái)只轉(zhuǎn)300過(guò)來(lái)就好,發(fā)現(xiàn)多轉(zhuǎn)了200,心里美滋滋。。。

事務(wù)1: A及時(shí)發(fā)現(xiàn)多轉(zhuǎn)了200,修改了轉(zhuǎn)300,提交事務(wù)。

最終,B再次查看賬戶的時(shí)候發(fā)現(xiàn)還是只多了300塊,白高興一場(chǎng),這種就是臟讀。當(dāng)隔離級(jí)別設(shè)置為Read uncommitted時(shí)可能會(huì)出現(xiàn)該情況。
若避開(kāi)臟讀,可以設(shè)置隔離級(jí)別為Read committed

2. 不可重復(fù)讀

一個(gè)事務(wù)先后讀取同一條記錄,而事務(wù)在兩次讀取之間該數(shù)據(jù)被其它事務(wù)所修改,則兩次讀取的數(shù)據(jù)不同,這種就是不可重復(fù)讀。

事務(wù)1:B去買(mǎi)東西,卡里有500塊錢(qián),消費(fèi)100,還沒(méi)提交事務(wù)。

事務(wù)2:B的老婆把B的500塊錢(qián)轉(zhuǎn)出去了,已提交事務(wù)。

事務(wù)1:B此時(shí)提交事務(wù),支付不了。再次讀取發(fā)現(xiàn)卡里沒(méi)錢(qián)支付。

當(dāng)隔離級(jí)別設(shè)置為Read committed,可以避免臟讀,但是可能會(huì)造成不可重復(fù)讀。
若避開(kāi)不可重復(fù)讀,可以設(shè)置隔離級(jí)別為Repeatable read。

3.幻讀

一個(gè)事務(wù)按相同的查詢條件重新讀取以前檢索過(guò)的數(shù)據(jù),卻發(fā)現(xiàn)其他事務(wù)插入了滿足其查詢條件的新數(shù)據(jù),這種現(xiàn)象就稱(chēng)為幻讀。

事務(wù)1:B的老婆查看B的卡消費(fèi)記錄,目前共消費(fèi)了500元。

事務(wù)2:B此時(shí)剛在外面請(qǐng)朋友吃完飯,付款了100,事務(wù)已提交。

B的老婆決定把賬單打印出來(lái),晚上跟B對(duì)賬,卻發(fā)現(xiàn)打印出來(lái)的消費(fèi)為600元。她剛才明明看到是500,怎么是600,難道是幻覺(jué)?

Mysql的默認(rèn)隔離級(jí)別為Repeatable read,可以避免不可重復(fù)讀,但是可能出現(xiàn)幻讀的情況。

如果要繼續(xù)解決幻讀,那么可以將隔離級(jí)別設(shè)置為最高級(jí)的Serializable,這時(shí)候事務(wù)都是按照順序執(zhí)行的,臟讀、幻讀、不可重復(fù)度都可以避免,但是性能很差。

四、手動(dòng)測(cè)試下事務(wù)的過(guò)程

可以在mysql里手動(dòng)去執(zhí)行事務(wù)提交的過(guò)程,輔助理解?,F(xiàn)在來(lái)模擬一個(gè)轉(zhuǎn)賬的過(guò)程,A給B轉(zhuǎn)賬500。

先創(chuàng)造下測(cè)試條件,造庫(kù)、表、數(shù)據(jù)。

-- 創(chuàng)建庫(kù)
CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 使用庫(kù)
USE shop;
-- 創(chuàng)建表
CREATE TABLE `account`(
	`id` INT(3) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(30) NOT NULL,
	`money` DECIMAL(9,2) NOT NULL,
	PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
-- 插入數(shù)據(jù)
INSERT INTO account(`name`,`money`)
VALUES ('A', 2000.00),('B', 10000.00)

上述sql都執(zhí)行完即可,現(xiàn)在有2條測(cè)試數(shù)據(jù)。

接下來(lái)手動(dòng)執(zhí)行事務(wù)提交的過(guò)程。

  • 關(guān)閉自動(dòng)提交
SET autocommit = 0; -- 關(guān)閉自動(dòng)提交,默認(rèn)是打開(kāi)

執(zhí)行sql。

  • 開(kāi)啟一個(gè)事務(wù)
START TRANSACTION -- 開(kāi)啟一個(gè)事務(wù)

執(zhí)行sql。

  • 定義事務(wù)里的sql
    開(kāi)啟事務(wù)后的sql,就是定義在一個(gè)事務(wù)里了。
UPDATE account SET money=money - 500 WHERE `name` = 'A' -- A減去500
UPDATE account SET money=money - 500 WHERE `name` = 'B' -- B增加500

執(zhí)行后,數(shù)據(jù)變更。A加了500,B少了500。

現(xiàn)在我不去提交,進(jìn)行回滾。

ROLLBACK; -- 回滾

數(shù)據(jù)變回最開(kāi)始的樣子。

重新執(zhí)行2條sql,并且提交事務(wù)。

UPDATE `shop`.`account` SET `money`=`money` - 500 WHERE `name` = 'A'; -- A減去500
UPDATE `shop`.`account` SET `money`=`money` + 500 WHERE `name` = 'B'; -- B增加500
COMMIT; -- 提交事務(wù)

數(shù)據(jù)修改成功,此時(shí)再次執(zhí)行回滾,數(shù)據(jù)已經(jīng)不可逆了。

以上就是Mysql數(shù)據(jù)庫(kù)事務(wù)的臟讀幻讀及不可重復(fù)讀詳解的詳細(xì)內(nèi)容,更多關(guān)于Mysql數(shù)據(jù)庫(kù)事務(wù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL的邏輯架構(gòu)及工作全流程

    MySQL的邏輯架構(gòu)及工作全流程

    這篇文章主要介紹了MySQL的邏輯架構(gòu)及工作全流程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • MySQL中CHAR和VARCHAR類(lèi)型演變和詳解

    MySQL中CHAR和VARCHAR類(lèi)型演變和詳解

    MySQL數(shù)據(jù)庫(kù)的varchar類(lèi)型在5.0.3以下的版本中的最大長(zhǎng)度限制為255,其數(shù)據(jù)范圍可以是0~255
    2012-06-06
  • mysql 從一個(gè)表中查數(shù)據(jù)并插入另一個(gè)表實(shí)現(xiàn)方法

    mysql 從一個(gè)表中查數(shù)據(jù)并插入另一個(gè)表實(shí)現(xiàn)方法

    這篇文章主要介紹了mysql 從一個(gè)表中查數(shù)據(jù)并插入另一個(gè)表實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 為mysql數(shù)據(jù)庫(kù)添加添加事務(wù)處理的方法

    為mysql數(shù)據(jù)庫(kù)添加添加事務(wù)處理的方法

    開(kāi)始首先說(shuō)明一下,mysql數(shù)據(jù)庫(kù)默認(rèn)的數(shù)據(jù)庫(kù)引擎是MyISAM,是不支持事務(wù)的,單數(shù)如果你添加了數(shù)據(jù)執(zhí)行語(yǔ)句是不會(huì)出錯(cuò)的,單數(shù)不管用,即便是回滾事務(wù),記錄也是插入進(jìn)去了,所有首先我們要做的第一步是更改數(shù)據(jù)庫(kù)引擎
    2011-07-07
  • Mysql常用命令匯總

    Mysql常用命令匯總

    這篇文章主要介紹了Mysql常用命令,都是mysql數(shù)據(jù)庫(kù)日常最基本的操作命令,感興趣的小伙伴們可以參考一下
    2015-11-11
  • MySQL Like語(yǔ)句的使用方法

    MySQL Like語(yǔ)句的使用方法

    本文介紹一下關(guān)于MySQL查詢字符串中包含字符的記錄一些常用方法,這里包括有REGEXP、FIND_IN_SET、Like
    2013-11-11
  • MySql服務(wù)器系統(tǒng)變量和狀態(tài)變量介紹

    MySql服務(wù)器系統(tǒng)變量和狀態(tài)變量介紹

    這篇文章主要介紹了MySql服務(wù)器系統(tǒng)變量和狀態(tài)變量介紹,本文分別講解了它們的作用、設(shè)置方法和獲取方法,需要的朋友可以參考下
    2014-12-12
  • Mysql數(shù)據(jù)庫(kù)亂碼問(wèn)題的對(duì)應(yīng)方式

    Mysql數(shù)據(jù)庫(kù)亂碼問(wèn)題的對(duì)應(yīng)方式

    今天小編就為大家分享一篇關(guān)于Mysql數(shù)據(jù)庫(kù)亂碼問(wèn)題的對(duì)應(yīng)方式,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • MySQL開(kāi)啟Slow慢查詢的方法示例

    MySQL開(kāi)啟Slow慢查詢的方法示例

    這篇文章主要給大家介紹了關(guān)于MySQL開(kāi)啟Slow慢查詢的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Advanced SQL Injection with MySQL

    Advanced SQL Injection with MySQL

    Advanced SQL Injection with MySQL...
    2006-12-12

最新評(píng)論

怀柔区| 彭水| 文成县| 民权县| 瓮安县| 泗水县| 宣威市| 应城市| 绥江县| 阿荣旗| 蓝田县| 台南市| 巴楚县| 凉山| 怀安县| 通州区| 丰台区| 洪洞县| 门头沟区| 且末县| 当雄县| 洱源县| 铜梁县| 泰安市| 同心县| 遵义市| 临澧县| 呼玛县| 高平市| 拉萨市| 桂林市| 禹州市| 外汇| 潮安县| 翼城县| 石首市| 陈巴尔虎旗| 贵德县| 永嘉县| 峨眉山市| 巫山县|