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

RR與RC隔離級(jí)別下索引和鎖的測(cè)試腳本示例代碼

 更新時(shí)間:2018年12月04日 15:00:54   作者:stuartlau  
這篇文章主要給大家介紹了關(guān)于RR與RC隔離級(jí)別下索引和鎖的測(cè)試腳本的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

基本概念

當(dāng)前讀與快照讀

在MVCC中,讀操作可以分成兩類(lèi):快照讀 (snapshot read)與當(dāng)前讀 (current read)。 快照讀,讀取的是記錄的可見(jiàn)版本 (有可能是歷史版本),不用加鎖。當(dāng)前讀,讀取的是記錄的最新版本,并且對(duì)返回的記錄,都會(huì)加上鎖,保證在事務(wù)結(jié)束前,這條數(shù)據(jù)都是最新版本。

快照讀:簡(jiǎn)單的select操作,屬于快照讀,不加鎖(Serializable除外)。

select * from table where ?;

當(dāng)前讀:特殊的讀操作,插入/更新/刪除操作,屬于當(dāng)前讀,需要加鎖?!?br />

select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values ();
update table set ? where ?;
delete from table where ?;

隔離級(jí)別與加鎖機(jī)制

  • Read Uncommitted 會(huì)發(fā)生臟讀,不考慮。
  • Read Committed (RC) 針對(duì)當(dāng)前讀,RC隔離級(jí)別保證對(duì)讀取到的記錄加鎖 (Gap Locking),存在幻讀現(xiàn)象。
  • Repeatable Read (RR) 針對(duì)當(dāng)前讀,RR隔離級(jí)別保證對(duì)讀取到的記錄加鎖 (Record Locking),同時(shí)保證對(duì)讀取的范圍加鎖,新的滿(mǎn)足查詢(xún)條件的記錄不能夠插入 (Gap Locking),不存在幻讀現(xiàn)象。
  • Serializable 所有的讀操作均為退化為當(dāng)前讀,讀寫(xiě)沖突,因此并發(fā)度急劇下降,不考慮。

測(cè)試腳本

-- 基本操作 --
-- 查詢(xún)事務(wù)隔離級(jí)別,默認(rèn)是RR
show variables like '%isolation%';

-- 設(shè)置事務(wù)隔離級(jí)別為RC
set session transaction isolation level read committed;


-- 數(shù)據(jù)初始化 --
begin;
drop table if exists user;
CREATE TABLE `user` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `email` varchar(64) NOT NULL,
 `age` int(11) NOT NULL,
 `address` varchar(64) NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `uniq_email` (`email`),
 KEY `idx_age` (`age`)
);

insert into user (email, age, address) values ("test1@elsef.com", 18, "address1");
insert into user (email, age, address) values ("test2@elsef.com", 20, "address2");
insert into user (email, age, address) values ("test3@elsef.com", 20, "address3");

commit;
select * from user;



-- 一、trx_id示例
begin;
SELECT TRX_ID FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();
select * from user;
SELECT TRX_ID FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();
SHOW ENGINE INNODB STATUS;
update user set age = 22 where id = 3;
-- 查詢(xún)事務(wù)id
SELECT TRX_ID FROM INFORMATION_SCHEMA.INNODB_TRX WHERE TRX_MYSQL_THREAD_ID = CONNECTION_ID();
-- INNODB 引擎狀態(tài)
SHOW ENGINE INNODB STATUS;
commit;

-- 二、可重復(fù)讀、不可重復(fù)讀示例

-- session1
set session transaction isolation level read committed;
begin;
-- session2
set session transaction isolation level repeatable read;
begin;
-- session1
select * from user;
-- session2
select * from user;
-- session3
begin;
insert into user (email, age, address) values ("test4@elsef.com", 30, "address4");
commit;
-- session1 這里因?yàn)槭荝C,所以可以讀到trx3提交的新數(shù)據(jù),這里如果是證明不可重復(fù)讀的話應(yīng)該使用update而不是insert
select * from user;
commit;
-- session2 這里因?yàn)槭荝R,所以不會(huì)讀到trx3提交的新數(shù)據(jù)
select * from user;
commit;

-- 三、快照讀幻讀示例
-- session1
set session transaction isolation level repeatable read;
begin;
-- 這里使用快照讀
select * from user;
-- session2
begin;
insert into user (email, age, address) values ("test4@elsef.com", 30, "address4");
commit;
select * from user;
-- session1
select * from user; -- 這里讀不到test4@的數(shù)據(jù),因?yàn)槭荝R
-- 這里發(fā)生了幻讀
insert into user (email, age, address) values ("test4@elsef.com", 30, "address4"); -- 插入失敗因?yàn)閑mail唯一索引沖突
commit;

-- 四、當(dāng)前讀幻讀示例
-- RC
-- session1
set session transaction isolation level read committed;
begin;
-- 這里會(huì)對(duì)所有滿(mǎn)足條件的age=20的記錄加鎖,因?yàn)槭荝C,所以沒(méi)有GAP鎖
delete from user where age = 20;
select * from user;
-- session2
set session transaction isolation level read committed;
begin;
-- 因?yàn)閠rx1沒(méi)有加GAP鎖,所以之類(lèi)可以插入age=20的記錄
insert into user (email, age, address) values ("test4@elsef.com", 20, "address4");
select * from user; -- 可以查到4條數(shù)據(jù),可以讀到trx1的刪除數(shù)據(jù),因?yàn)槭荝C,trx1未提交所以沒(méi)影響trx2
commit;
-- session1
select * from user; -- 可以讀到trx2新插入的數(shù)據(jù),雖然trx1是當(dāng)前讀,但是并未添加相應(yīng)的next-key鎖,沒(méi)有阻止trx2的新數(shù)據(jù)插入
commit;

--RR
-- session1
set session transaction isolation level repeatable read;
begin;
delete from user where age = 20;
select * from user;
-- session2
begin;
-- 這里會(huì)阻塞,因?yàn)閠rx1在age=20周?chē)恿薌AP鎖
-- 非唯一索引,首先,通過(guò)索引定位到第一條滿(mǎn)足查詢(xún)條件的記錄,加記錄上的X鎖,加GAP上的GAP鎖,然后加主鍵聚簇索引上的記錄X鎖;
-- 然后讀取下一條,重復(fù)進(jìn)行。直至進(jìn)行到第一條不滿(mǎn)足條件的記錄,此時(shí),不需要加記錄X鎖,但是仍舊需要加GAP鎖,最后返回結(jié)束。
insert into user (email, age, address) values ("test4@elsef.com", 20, "address4");
-- 直到超時(shí),ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
-- 此時(shí)如果查詢(xún)可以看到3條記錄
commit;
-- session1
-- 此時(shí)只能看到1條記錄,另外兩條被刪除了
select * from user;
commit;

-- 唯一索引+RC
-- session1
set session transaction isolation level read committed;
begin;
delete from user where email = "test3@elsef.com";
-- session2
begin;
-- 可以讀到,因?yàn)閠rx1是RC
select * from user where email = "test3@elsef.com";
-- 嘗試更新這個(gè)記錄的age,會(huì)阻塞直到超時(shí),因?yàn)閑mail是唯一索引已經(jīng)被trx1鎖住了,同時(shí)也會(huì)在對(duì)應(yīng)的主鍵索引上加鎖
-- 注意這里操作的id=3就是trx1中操作的email的同一行記錄
update user set age = 40 where id = 3;
-- session1
commit;
-- session2
commit;

-- 無(wú)索引+RC
-- session1
set session transaction isolation level read committed;
begin;
-- 由于address字段無(wú)索引,所以Innodb會(huì)對(duì)所有行進(jìn)行加鎖,由MySQL server進(jìn)行判斷并釋放鎖
delete from user where address = "address3";
-- session2
set session transaction isolation level read committed;
begin;
-- 這一行會(huì)成功,因?yàn)檫@一行沒(méi)有加鎖(先加了后釋放了)
update user set age = 10 where address = "address2";
-- 這一行同樣會(huì)被阻塞,原因是它已經(jīng)被trx1的語(yǔ)句加了鎖了,全部符合條件的都加鎖了
update user set age = 10 where address = "address3";
-- session1
commit;
-- session2
commit;

-- 非唯一索引+RR
-- session1
set session transaction isolation level repeatable read;
begin;
delete from user where age = 20;
-- session2
set session transaction isolation level repeatable read;
begin;
-- 這里會(huì)阻塞,因?yàn)閠rx1中已經(jīng)鎖住了age=20的記錄以及加上了GAP鎖,所以這里18已經(jīng)落入鎖區(qū)間
insert into user (email, age, address) values ("test4@elsef.com", 18, "address4");
-- session1
commit;
-- session2
commit;

-- 無(wú)索引RR
-- session1
set session transaction isolation level repeatable read;
begin;
-- 沒(méi)有索引,那么會(huì)鎖上表中的所有記錄,同時(shí)會(huì)鎖上主鍵索引上的所有GAP,杜絕所有的并發(fā)更新操作
delete from user where address = "address3";
-- session2
set session transaction isolation level repeatable read;
begin;
-- 這里會(huì)阻塞,原因是主鍵已經(jīng)被加上了GAP鎖,所以新的插入不能執(zhí)行成功
insert into user (email, age, address) values ("test4@elsef.com", 18, "address4");
-- session1
commit;
-- session2
commit;

-- 死鎖 簡(jiǎn)單示例
-- session1
begin;
delete from user where id = 1;
-- session2
begin;
delete from user where id = 3;
-- session1
delete from user where id = 3;
-- seession2
-- 這里MySQL判斷發(fā)生了死鎖,中斷了一個(gè)trx
-- ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
delete from user where id = 1;
-- session1
rollback;
-- session2;
rollback;

-- 五、死鎖 insert示例
drop table if exists t1;
begin;
create table t1 (
 `id` bigint not null auto_increment,
 primary key (`id`)
);
insert into t1 values(1);
insert into t1 values(5);
commit;
select * from t1;
-- session1
begin;
insert into t1 values (2);
-- sessioin2
begin;
-- 這里會(huì)阻塞
insert into t1 values (2);
-- session3
begin;
-- 這里會(huì)阻塞
insert into t1 values (2);
-- session1;
-- 此時(shí)回滾,trx2和trx3收到通知,MySQL自動(dòng)中斷一個(gè)trx,因?yàn)榘l(fā)生了死鎖
-- ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
rollback;
--session2;
rollback;
--session3;
rollback;

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • windows 10 下mysql-8.0.17-winx64的安裝方法圖解

    windows 10 下mysql-8.0.17-winx64的安裝方法圖解

    這篇文章主要介紹了windows 10 mysql-8.0.17-winx64的方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • SQL查詢(xún)超時(shí)的設(shè)置方法(關(guān)于timeout的處理)

    SQL查詢(xún)超時(shí)的設(shè)置方法(關(guān)于timeout的處理)

    為了優(yōu)化OceanBase的query timeout設(shè)置方式,特調(diào)研MySQL關(guān)于timeout的處理,下面與大家分享下處理記錄,感興趣的朋友可以參考下哈
    2013-04-04
  • Linux下mysql 8.0.25 安裝配置方法圖文教程

    Linux下mysql 8.0.25 安裝配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了Linux下mysql 8.0.25 安裝配置方法圖文教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • MySQL 數(shù)據(jù)庫(kù)雙向鏡像、循環(huán)鏡像(復(fù)制)

    MySQL 數(shù)據(jù)庫(kù)雙向鏡像、循環(huán)鏡像(復(fù)制)

    在MySQL數(shù)據(jù)庫(kù)鏡像的貼子中,主數(shù)據(jù)庫(kù)A 的數(shù)據(jù)鏡像到從數(shù)據(jù)庫(kù)B,是單向的,Zen Cart網(wǎng)店的數(shù)據(jù)讀寫(xiě)都必須在數(shù)據(jù)庫(kù)A進(jìn)行,結(jié)果會(huì)自動(dòng)鏡像到數(shù)據(jù)庫(kù)B中。但是對(duì)數(shù)據(jù)庫(kù)B的直接操作,不會(huì)影響數(shù)據(jù)庫(kù)A。
    2011-05-05
  • MySQL MGR搭建過(guò)程中常遇見(jiàn)的問(wèn)題及解決辦法

    MySQL MGR搭建過(guò)程中常遇見(jiàn)的問(wèn)題及解決辦法

    這篇文章主要介紹了MySQL MGR搭建過(guò)程中常遇見(jiàn)的問(wèn)題及解決辦法,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03
  • Mysql全局ID生成方法

    Mysql全局ID生成方法

    本文給大家介紹mysql全局id生成方法,涉及到mysql全局id相關(guān)知識(shí),感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • MySQL 權(quán)限控制詳解

    MySQL 權(quán)限控制詳解

    這篇文章主要介紹了MySQL 權(quán)限控制詳解的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-03-03
  • MySQL 5.7.30 安裝與升級(jí)問(wèn)題詳細(xì)教程

    MySQL 5.7.30 安裝與升級(jí)問(wèn)題詳細(xì)教程

    這篇文章主要介紹了MySQL 5.7.30 的安裝與升級(jí)教程(所有可能的坑都在這里),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • mysql的case when字段為空,null的問(wèn)題

    mysql的case when字段為空,null的問(wèn)題

    這篇文章主要介紹了mysql的case when字段為空,null的問(wèn)題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • MySql視圖觸發(fā)器存儲(chǔ)過(guò)程詳解

    MySql視圖觸發(fā)器存儲(chǔ)過(guò)程詳解

    這篇文章主要介紹了MySql視圖觸發(fā)器存儲(chǔ)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05

最新評(píng)論

井陉县| SHOW| 望奎县| 潜山县| 北辰区| 九台市| 米脂县| 黄梅县| 城市| 桦南县| 林芝县| 敦化市| 云龙县| 苏尼特右旗| 黎平县| 东乡县| 玉田县| 灵丘县| 济南市| 开化县| 浮梁县| 铜陵市| 荥阳市| 友谊县| 根河市| 罗城| 饶阳县| 迁安市| 本溪| 巍山| 理塘县| 凤山县| 高青县| 丰原市| 广宁县| 通城县| 出国| 白沙| 沂南县| 伽师县| 栾川县|