欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

首先說(shuō)一下數(shù)據(jù)庫(kù)事務(wù)的四大特性

呈貢網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,呈貢網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為呈貢成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營(yíng)銷網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的呈貢做網(wǎng)站的公司定做!

1 ACID

事務(wù)的四大特性是ACID(不是"酸"....)

(1) A:原子性(Atomicity)

原子性指的是事務(wù)要么完全執(zhí)行,要么完全不執(zhí)行.

(2) C:一致性(Consistency)

事務(wù)完成時(shí),數(shù)據(jù)必須處于一致的狀態(tài).若事務(wù)執(zhí)行途中出錯(cuò),會(huì)回滾到之前的事務(wù)沒(méi)有執(zhí)行前的狀態(tài),這樣數(shù)據(jù)就處于一致的狀態(tài).若事務(wù)出錯(cuò)后沒(méi)有回滾,部分修改的內(nèi)容寫入到了數(shù)據(jù)庫(kù)中,這時(shí)數(shù)據(jù)就是不一致的狀態(tài).

(3) I:隔離性(Isolation)

同時(shí)處理多個(gè)事務(wù)時(shí),一個(gè)事務(wù)的執(zhí)行不能被另一個(gè)事務(wù)所干擾,事務(wù)的內(nèi)部操作與其他并發(fā)事務(wù)隔離.

(4) D:持久性(Durability)

事務(wù)提交后,對(duì)數(shù)據(jù)的修改是永久性的.

2 MySQL的鎖

Mysql的鎖其實(shí)可以按很多種形式分類:

  • 按加鎖機(jī)制分,可分為樂(lè)觀鎖與悲觀鎖.
  • 按兼容性來(lái)分,可分為X鎖與S鎖.
  • 按鎖粒度分,可分為表鎖,行鎖,頁(yè)鎖.
  • 按鎖模式分,可分為記錄鎖,gap鎖,next-key鎖,意向鎖,插入意向鎖.

這里主要討論S鎖,X鎖,樂(lè)觀鎖與悲觀鎖.

(1) S鎖與X鎖

S鎖與X鎖是InnoDB引擎實(shí)現(xiàn)的兩種標(biāo)準(zhǔn)行鎖機(jī)制.查看默認(rèn)引擎可使用

show variables like '%storage_engine%';

作者的mysql版本為8.0.17,結(jié)果如下:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

先建好測(cè)試庫(kù)與測(cè)試表,很簡(jiǎn)單,表就兩個(gè)字段.

create database test;
use test;
create table a
(
id int primary key auto_increment,
money int
);

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

Ⅰ.S鎖

S鎖也叫共享鎖,讀鎖,數(shù)據(jù)只能被讀取不能被修改.
玩一下,上鎖!

lock table a read;

然后.....

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

只能讀不能改,刪,也不能增.

Ⅱ.X鎖

X鎖也叫排他鎖,寫鎖,一個(gè)事務(wù)對(duì)表加鎖后,其他事務(wù)就不能對(duì)其進(jìn)行加鎖與增刪查改操作.

設(shè)置手動(dòng)提交,開啟事務(wù),上X鎖.

set autocmmmit=0;
start transaction;
lock table a write;

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

在開啟另一個(gè)事務(wù),使用select語(yǔ)句.

set autocommit=0;
start transaction;
select * from a;

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

這里是阻塞select操作,因?yàn)橐恢倍紱](méi)釋放X鎖.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

同樣也不能再加鎖,也是阻塞中.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

回到原來(lái)那個(gè)加鎖的事務(wù),嗯,什么事也沒(méi)有,正常讀寫.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

釋放鎖后:

unlock table;

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

在另一個(gè)事務(wù)中可以看到中斷時(shí)間.

(2) 樂(lè)觀鎖與悲觀鎖

Ⅰ.樂(lè)觀鎖

樂(lè)觀鎖就是總是假設(shè)是最好的情況,每次去操作的時(shí)候都不會(huì)上鎖,但在更新時(shí)會(huì)判斷有沒(méi)有其他操作去更新這個(gè)數(shù)據(jù),是一種寬松的加鎖機(jī)制.
mysql本身沒(méi)有提供樂(lè)觀鎖的支持,需要自己來(lái)實(shí)現(xiàn),常用的方法有版本控制和時(shí)間戳控制兩種.

  • 版本控制
    版本控制就是為表增加一個(gè)version字段,讀取數(shù)據(jù)時(shí)連同這個(gè)version字段一起讀出來(lái),之后進(jìn)行更新操作,版本號(hào)加1,再將提交的數(shù)據(jù)的版本號(hào)與數(shù)據(jù)庫(kù)中的版本號(hào)進(jìn)行比較,若提交的數(shù)據(jù)的版本號(hào)大于數(shù)據(jù)庫(kù)中的版本號(hào)才會(huì)進(jìn)行更新.

    舉個(gè)例子,假設(shè)此時(shí)version=1,A進(jìn)行操作,更新數(shù)據(jù)后version=2,與此同時(shí)B也進(jìn)行操作,更新數(shù)據(jù)后version=2,A先完成操作,率先將數(shù)據(jù)庫(kù)中的version設(shè)置為2,此時(shí)B提交,B的version與數(shù)據(jù)庫(kù)中的version一樣,不接受B的提交.

  • 時(shí)間戳控制
    時(shí)間戳控制與版本控制差不多,把version字段改為timestamp字段
    還有一種實(shí)現(xiàn)方法叫CAS算法,這個(gè)作者不怎么了解,有興趣可以自行搜索.

Ⅱ.悲觀鎖

悲觀鎖就是總是假設(shè)最壞的情況,在整個(gè)數(shù)據(jù)處理狀態(tài)中數(shù)據(jù)處于鎖定狀態(tài),悲觀鎖的實(shí)現(xiàn)往往依靠數(shù)據(jù)庫(kù)的鎖機(jī)制.每次在拿到數(shù)據(jù)前都會(huì)上鎖.
mysql在調(diào)用一些語(yǔ)句時(shí)會(huì)上悲觀鎖,如(先關(guān)閉自動(dòng)提交,開啟事務(wù)):

set autocommit=0;
start transaction;

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

兩個(gè)事務(wù)都這樣操作,然后其中一個(gè)事務(wù)輸入:

select * from a where xxx for update;

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

在另一事務(wù)也這樣輸入:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

這時(shí)語(yǔ)句會(huì)被阻塞,直到上鎖的那個(gè)事務(wù)commit(解開悲觀鎖).

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

在另一事務(wù)中可以看到這個(gè)事務(wù)被阻塞了2.81s.

*** lock in share mode.

也會(huì)加上悲觀鎖.

4 臟讀,幻讀,不可重復(fù)讀與兩類丟失更新

(1) 臟讀

臟讀是指一個(gè)事務(wù)讀取到了另一事務(wù)未提交的數(shù)據(jù),造成select前后數(shù)據(jù)不一致.

比如事務(wù)A修改了一些數(shù)據(jù),但沒(méi)有提交,此時(shí)事務(wù)B卻讀取了,這時(shí)事務(wù)B就形成了臟讀,一般事務(wù)A的后續(xù)操作是回滾,事務(wù)B讀取到了臨時(shí)數(shù)值.

事務(wù)A事務(wù)B
開始事務(wù) 開始事務(wù)
更新X,舊值X=1,新值X=2 ?
? 讀取X,X=2(臟讀)
回滾X=1 ?
結(jié)束事務(wù)(X=1) 結(jié)束事務(wù)

(2) 幻讀

幻讀是指并不是指同一個(gè)事務(wù)執(zhí)行兩次相同的select語(yǔ)句得到的結(jié)果不同,而是指select時(shí)不存在某記錄,但準(zhǔn)備插入時(shí)發(fā)現(xiàn)此記錄已存在,無(wú)法插入,這就產(chǎn)生了幻讀.

事務(wù)A事務(wù)B
開始事務(wù) 開始事務(wù)
select某個(gè)數(shù)據(jù)為空,準(zhǔn)備插入一個(gè)新數(shù)據(jù) ?
? 插入一個(gè)新數(shù)據(jù)
? 提交,結(jié)束事務(wù)
插入數(shù)據(jù),發(fā)現(xiàn)插入失敗,由于事務(wù)B已插入相同數(shù)據(jù) ?
結(jié)束事務(wù) ?

(3) 不可重復(fù)讀

不可重復(fù)讀指一個(gè)事務(wù)讀取到了另一事務(wù)已提交的數(shù)據(jù),造成select前后數(shù)據(jù)不一致.
比如事務(wù)A修改了一些數(shù)據(jù)并且提交了,此時(shí)事務(wù)B卻讀取了,這時(shí)事務(wù)B就形成了不可重復(fù)讀.

事務(wù)A事務(wù)B
開始事務(wù) 開始事務(wù)
讀取X=1 讀取X=1
更新X=2 ?
提交,結(jié)束事務(wù) ?
? 讀取X=2
? 結(jié)束事務(wù)

(4) 第一類丟失更新

第一類丟失更新就是兩個(gè)事務(wù)同時(shí)更新一個(gè)數(shù)據(jù),一個(gè)事務(wù)更新完畢并提交后,另一個(gè)事務(wù)回滾,造成提交的更新丟失.

事務(wù)A事務(wù)B
開始事務(wù) 開始事務(wù)
讀取X=1 讀取X=1
修改X=2 修改X=3
? 提交,結(jié)束事務(wù)
回滾 ?
結(jié)束事務(wù)(X=1) X=1,X本應(yīng)為提交的3

(5) 第二類丟失更新

第二類丟失更新就是兩個(gè)事務(wù)同時(shí)更新一個(gè)數(shù)據(jù),先更新的事務(wù)提交的數(shù)據(jù)會(huì)被后更新的事務(wù)提交的數(shù)據(jù)覆蓋,即先更新的事務(wù)提交的數(shù)據(jù)丟失.

事務(wù)A事務(wù)B
開始事務(wù) 開始事務(wù)
讀取X=1 讀取X=1
更新X=2 ?
提交事務(wù),X=2,結(jié)束 ?
? 更新X=3
? 提交事務(wù),X=3,事務(wù)A的更新丟失,結(jié)束

5 封鎖協(xié)議與隔離級(jí)別

封鎖協(xié)議就是在用X鎖或S鎖時(shí)制定的一些規(guī)則,比如鎖的持續(xù)時(shí)間,鎖的加鎖時(shí)間等.不同的封鎖協(xié)議對(duì)應(yīng)不同的隔離級(jí)別.事務(wù)的隔離級(jí)別一共有4種,由低到高分別是Read uncommitted,Read committed,Repeatable read,Serializable,分別對(duì)應(yīng)的相應(yīng)的封鎖協(xié)議等級(jí).

(1) 一級(jí)封鎖協(xié)議

一級(jí)封鎖協(xié)議對(duì)應(yīng)的是Read uncommitted隔離級(jí)別,Read uncommitted,讀未提交,一個(gè)事務(wù)可以讀取另一個(gè)事務(wù)未提交的數(shù)據(jù),這是最低的級(jí)別.一級(jí)封鎖協(xié)議本質(zhì)上是在事務(wù)修改數(shù)據(jù)之前加上X鎖,直到事務(wù)結(jié)束后才釋放,事務(wù)結(jié)束包括正常結(jié)束(commit)與非正常結(jié)束(rollback).

一級(jí)封鎖協(xié)議不會(huì)造成更新丟失,但可能引發(fā)臟讀,幻讀,不可重復(fù)讀.
設(shè)置手動(dòng)提交與事務(wù)隔離等級(jí)為read uncommited,并開啟事務(wù)(注意要先設(shè)置事務(wù)等級(jí)再開啟事務(wù)).

set autocommit=0;
set session transaction isolation level read uncommitted;
start transaction;

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

(中間有一行打多了一個(gè)t可以忽略.....)

a.引發(fā)臟讀

在一個(gè)事務(wù)中修改表中的值,不提交,另一個(gè)事務(wù)可以select到未提交的值.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

出現(xiàn)了臟讀.

b.引發(fā)幻讀

在一個(gè)事務(wù)中插入一條數(shù)據(jù),提交.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一事務(wù)中select時(shí)沒(méi)有,準(zhǔn)備insert,但是insert時(shí)卻提示已經(jīng)存在.引發(fā)幻讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

c.引發(fā)不可重復(fù)讀

未操作提交前:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一事務(wù)修改并提交:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

再次讀:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

引發(fā)不可重復(fù)讀.

(2) 二級(jí)封鎖協(xié)議

二級(jí)封鎖協(xié)議本質(zhì)上在一級(jí)協(xié)議的基礎(chǔ)上(在修改數(shù)據(jù)時(shí)加X(jué)鎖),在讀數(shù)據(jù)時(shí)加上S鎖,讀完后立即釋放S鎖,可以避免臟讀.但有可能出現(xiàn)不可重復(fù)讀與幻讀.二級(jí)封鎖協(xié)議對(duì)應(yīng)的是Read committed與Repeatable Read隔離級(jí)別.

先設(shè)置隔離等級(jí)

set session transaction isolation level read committed;

Ⅰ.Read committed

Read committed,讀提交,讀提交可以避免臟讀,但可能出現(xiàn)幻讀與不可重復(fù)讀.

a.避免臟讀

開啟一個(gè)事務(wù)并更新值,在這個(gè)事務(wù)中money=100(更新后)

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一事務(wù)中money為未更新前的值,這就避免了臟讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

注意,事實(shí)上臟讀在read committed隔離級(jí)別下是不被允許的,但是mysql不會(huì)阻塞查詢,而是返回未修改之前數(shù)據(jù)的備份,這種機(jī)制叫MVCC機(jī)制(多版本并發(fā)控制).

b.引發(fā)幻讀

在一個(gè)事務(wù)中插入數(shù)據(jù)并提交.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一事務(wù)中不能插入"不存在"的數(shù)據(jù),出現(xiàn)幻讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

c.引發(fā)不可重復(fù)讀

事務(wù)修改并提交前:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

事務(wù)修改并提交:

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

出現(xiàn)不可重復(fù)讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

Ⅱ.Repeatable read

Repeatable read比Read committed嚴(yán)格一點(diǎn),是Mysql的默認(rèn)級(jí)別,讀取過(guò)程更多地受到MVCC影響,可防止不可重復(fù)讀與臟讀,但仍有可能出現(xiàn)幻讀.

a.避免臟讀

在一個(gè)事務(wù)中修改數(shù)據(jù),不提交.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一事務(wù)中兩次select的結(jié)果都不變,沒(méi)有出現(xiàn)臟讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

b.避免不可重復(fù)讀

一個(gè)事務(wù)修改數(shù)據(jù)并提交.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一事務(wù)中select的結(jié)果沒(méi)有發(fā)生改變,即沒(méi)有出現(xiàn)不可重復(fù)讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

c.引發(fā)幻讀

同理,一個(gè)事務(wù)插入一條數(shù)據(jù)并提交.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

另一個(gè)事務(wù)插入時(shí)出現(xiàn)幻讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

(3) 三級(jí)封鎖協(xié)議

三級(jí)封鎖協(xié)議,在一級(jí)封鎖協(xié)議的基礎(chǔ)上(修改時(shí)加X(jué)鎖),讀數(shù)據(jù)時(shí)加上S鎖(與二級(jí)類似),但是直到事務(wù)結(jié)束后才釋放S鎖,可以避免幻讀,臟讀與不可重復(fù)讀.三級(jí)封鎖協(xié)議對(duì)應(yīng)的隔離級(jí)別是Serializable.

先設(shè)置Serializable隔離級(jí)別

set session transaction isolation level serializable

a.避免臟讀

設(shè)置事務(wù)隔離等級(jí)后開啟事務(wù)并update,發(fā)現(xiàn)堵塞.從而避免了臟讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

b.避免幻讀

插入時(shí)直接阻塞,避免了幻讀.

一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離

c.避免不可重復(fù)讀

在臟讀的例子中可以知道,update會(huì)被堵塞,都不能提交事務(wù),因此也避免了不可重復(fù)讀.

6 兩段鎖協(xié)議

事務(wù)必須分為兩個(gè)階段對(duì)數(shù)據(jù)進(jìn)行加鎖與解鎖,兩端鎖協(xié)議叫2PL(不是2PC),所有的加鎖都在解鎖之前進(jìn)行.

(1) 加鎖

加鎖會(huì)在更新或者

select *** for update
*** lock in share mode

時(shí)進(jìn)行

(2) 解鎖

解鎖在事務(wù)結(jié)束時(shí)進(jìn)行,事務(wù)結(jié)束包括rollback與commit.

參考鏈接
1:ACID1

2:ACID2

3:mysql的鎖1

4:樂(lè)觀鎖與悲觀鎖1

5:樂(lè)觀鎖與悲觀鎖2

6:樂(lè)觀鎖與悲觀鎖3

7:mysql修改事務(wù)隔離等級(jí)

8:mysql三級(jí)封鎖與二段鎖

9:數(shù)據(jù)庫(kù)封鎖協(xié)議

10:mysql事務(wù)隔離機(jī)制1

11:mysql事務(wù)隔離機(jī)制2

12:mysql幻讀

13:mysql臟讀,不可重復(fù)讀與幻讀

14:mysql兩段鎖1

15:mysql兩段鎖2

網(wǎng)站欄目:一文帶你理解臟讀,幻讀,不可重復(fù)讀與mysql的鎖,事務(wù)隔離
URL分享:http://chinadenli.net/article42/jiidhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、微信公眾號(hào)、營(yíng)銷型網(wǎng)站建設(shè)、App開發(fā)網(wǎng)站策劃、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)