MySQL事務(wù)隔離級(jí)別和一致性詳解
一、如何理解隔離性
MySQL服務(wù)可能會(huì)同時(shí)被多個(gè)客戶端進(jìn)程(線程)訪問(wèn),訪問(wèn)的方式以事務(wù)方式進(jìn)行
一個(gè)事務(wù)可能由多條SQL構(gòu)成,也就意味著,任何一個(gè)事務(wù),都有執(zhí)行前,執(zhí)行中,執(zhí)行后的階段。而所謂的原子性,其實(shí)就是讓用戶層,要么看到執(zhí)行前,要么看到執(zhí)行后。執(zhí)行中出現(xiàn)問(wèn)題,可以隨時(shí)回滾。所以單個(gè)事務(wù),對(duì)用戶表現(xiàn)出來(lái)的特性,就是原子性。
但,畢竟所有事務(wù)都要有個(gè)執(zhí)行過(guò)程,那么在多個(gè)事務(wù)各自執(zhí)行多個(gè)SQL的時(shí)候,就還是有可能會(huì)出現(xiàn)互相影響的情況。比如:多個(gè)事務(wù)同時(shí)訪問(wèn)同一張表,甚至同一行數(shù)據(jù)。 就如同你媽媽給你說(shuō):你要么別學(xué),要學(xué)就學(xué)到最好。至于你怎么學(xué),中間有什么困難,你媽媽不關(guān)心。那么 你的學(xué)習(xí),對(duì)你媽媽來(lái)講,就是原子的。那么你學(xué)習(xí)過(guò)程中,很容易受別人干擾,此時(shí),就需要將你的學(xué)習(xí)隔離開(kāi),保證你的學(xué)習(xí)環(huán)境是健康的。
- 數(shù)據(jù)庫(kù)中,為了保證事務(wù)執(zhí)行過(guò)程中盡量不受干擾,就有了一個(gè)重要特征:隔離性
- 數(shù)據(jù)庫(kù)中,允許事務(wù)受不同程度的干擾,就有了一種重要特征:隔離級(jí)別
二、隔離性的體現(xiàn)
講個(gè)小故事,如果同一時(shí)間有一個(gè)update操作和一個(gè)select操作,那么哪一個(gè)先執(zhí)行呢??如果是update先執(zhí)行,那么select拿到的就是最新的數(shù)據(jù),而如果是select先執(zhí)行,那么拿到的是老的數(shù)據(jù),大多數(shù)人肯定會(huì)覺(jué)得肯定要讓update先執(zhí)行而看到新數(shù)據(jù),但實(shí)際上這種想法是不太合理的。比方拿時(shí)間線來(lái)說(shuō),我們的父母出生得比我們?cè)纾敲粗钡剿麄兩挛业倪@段時(shí)間里,我是看不到這個(gè)世界的,我只看得到自己出生之后所在時(shí)間線的世界,而以前已經(jīng)過(guò)世的親人也看不到我現(xiàn)在所看到的世界…… 這就說(shuō)明了我們站在上帝視角,每一個(gè)人都只能看到自己活著時(shí)候世界所對(duì)應(yīng)的樣子,所以我們時(shí)間線一直在延展的時(shí)候,每個(gè)人看到的世界都應(yīng)該是不一樣的,這才符合自然規(guī)律,人與人之間具有隔離性,因此讓每一個(gè)事務(wù)都看到最新的數(shù)據(jù)是不合理的,而是應(yīng)該讓每一個(gè)事務(wù)在他到來(lái)時(shí)看到他應(yīng)該看到的數(shù)據(jù)。這就是隔離性的體現(xiàn)。(所以u(píng)pdata和select誰(shuí)先跑取決于誰(shuí)先來(lái))
可是先到來(lái)的并不一定先退出,所以即使我先到來(lái)了但是操作時(shí)間很長(zhǎng),你在我操作結(jié)束之前也是看不到我更新后的數(shù)據(jù)的,這也是隔離性的體現(xiàn)。
舉個(gè)例子,你的朋友要轉(zhuǎn)賬100給你,在你朋友給你轉(zhuǎn)錢的時(shí)候,你一定是得等他轉(zhuǎn)錢事務(wù)都完成了才能查到。這是正常的隔離性。但是隔離性具體要隔離到什么程度,我們就有了隔離級(jí)別的概念!(比方說(shuō)我們?nèi)シb店,如果是換褲子,我們會(huì)進(jìn)試衣間,如果是換上衣,我們會(huì)根據(jù)情況,如果是換鞋子,那直接在外面換就可以了,所以這就是因?yàn)橛绊懖煌鴮?dǎo)致隔離級(jí)別的不同)
三、隔離級(jí)別(讀寫并發(fā))
1、讀未提交【Read Uncommitted】: 在該隔離級(jí)別,所有的事務(wù)都可以看到其他事務(wù)沒(méi)有提交的執(zhí)行結(jié)果。 (實(shí)際生產(chǎn)中不可能使用這種隔離級(jí)別的),但是相當(dāng)于沒(méi)有任何隔離性,也會(huì)有很多并發(fā)問(wèn)題,如臟讀,幻讀,不可重復(fù)讀等,我們上面為了做實(shí)驗(yàn)方便,用的就是這個(gè)隔離性。
2、讀提交【Read Committed】 :該隔離級(jí)別是大多數(shù)數(shù)據(jù)庫(kù)的默認(rèn)的隔離級(jí)別(不是 MySQL 默認(rèn)的)。它滿足了隔離的簡(jiǎn)單定義:一個(gè)事務(wù)只能看到其他的已經(jīng)提交的事務(wù)所做的改變。(就是你提交了我還沒(méi)退出就能看到)這種隔離級(jí)別會(huì)引起不可重復(fù)讀, 即一個(gè)事務(wù)執(zhí)行時(shí),如果多次 select, 可能得到不同的結(jié)果。
3、可重復(fù)讀【Repeatable Read】: 這是 MySQL 默認(rèn)的隔離級(jí)別,它確保同一個(gè)事務(wù),在執(zhí)行中,多次讀取操作數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行。(就是你提交了,并且我結(jié)束了,才能看到 )但是會(huì)有幻讀問(wèn)題。
4、串行化【Serializable】: 這是事務(wù)的最高隔離級(jí)別,它通過(guò)強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決了幻讀的問(wèn)題。(就是你結(jié)束了我才能執(zhí)行,保證數(shù)據(jù)絕對(duì)安全)它在每個(gè)讀的數(shù)據(jù)行上面加上共享鎖。但是可能會(huì)導(dǎo)致超時(shí)和鎖競(jìng)爭(zhēng)(這種隔離級(jí)別太極端, 實(shí)際生產(chǎn)基本不使用)
隔離級(jí)別如何實(shí)現(xiàn):隔離,基本都是通過(guò)鎖實(shí)現(xiàn)的,不同的隔離級(jí)別,鎖的使用是不同的。常見(jiàn)有,表鎖,行鎖,讀鎖,寫鎖,間隙鎖(GAP),Next-Key鎖(GAP+行鎖)等。不過(guò),我們目前現(xiàn)有這個(gè)認(rèn)識(shí)就行,先關(guān)注上層使用。
上面四種隔離級(jí)別關(guān)注的場(chǎng)景都是當(dāng)有一個(gè)人在進(jìn)行寫的時(shí)候另一個(gè)人來(lái)讀(讀寫并發(fā))
四、查看與設(shè)置隔離性
-- 查看 mysql> SELECT @@global.tx_isolation; --查看全局隔級(jí)別 +-----------------------+ | @@global.tx_isolation | +-----------------------+ | REPEATABLE-READ | +-----------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@session.tx_isolation; --查看會(huì)話(當(dāng)前)全局隔級(jí)別(默認(rèn)用全局的初始化) +------------------------+ | @@session.tx_isolation | +------------------------+ | REPEATABLE-READ | +------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@tx_isolation; --默認(rèn)同上 +-----------------+ | @@tx_isolation | +-----------------+ | REPEATABLE-READ | +-----------------+ 1 row in set, 1 warning (0.00 sec) --設(shè)置 -- 設(shè)置當(dāng)前會(huì)話 or 全局隔離級(jí)別語(yǔ)法 SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE} --設(shè)置當(dāng)前會(huì)話隔離性,另起一個(gè)會(huì)話,看不多,只影響當(dāng)前會(huì)話 mysql> set session transaction isolation level serializable; -- 串行化 Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@global.tx_isolation; --全局隔離性還是RR +-----------------------+ | @@global.tx_isolation | +-----------------------+ | REPEATABLE-READ | +-----------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@session.tx_isolation; --會(huì)話隔離性成為串行化 +------------------------+ | @@session.tx_isolation | +------------------------+ | SERIALIZABLE | +------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@tx_isolation; --同上 +----------------+ | @@tx_isolation | +----------------+ | SERIALIZABLE | +----------------+ 1 row in set, 1 warning (0.00 sec) --設(shè)置全局隔離性,另起一個(gè)會(huì)話,會(huì)被影響 mysql> set global transaction isolation level READ UNCOMMITTED; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@global.tx_isolation; +-----------------------+ | @@global.tx_isolation | +-----------------------+ | READ-UNCOMMITTED | +-----------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@session.tx_isolation; +------------------------+ | @@session.tx_isolation | +------------------------+ | READ-UNCOMMITTED | +------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SELECT @@tx_isolation; +------------------+ | @@tx_isolation | +------------------+ | READ-UNCOMMITTED | +------------------+ 1 row in set, 1 warning (0.00 sec) -- 注意,如果沒(méi)有現(xiàn)象,關(guān)閉mysql客戶端,重新連接。
五、讀未提交【Read Uncommitted】
--幾乎沒(méi)有加鎖,雖然效率高,但是問(wèn)題太多,嚴(yán)重不建議采用
--終端A -- 設(shè)置隔離級(jí)別為 讀未提交 mysql> set global transaction isolation level read uncommitted; Query OK, 0 rows affected (0.00 sec) --重啟客戶端 mysql> select @@tx_isolation; +------------------+ | @@tx_isolation | +------------------+ | READ-UNCOMMITTED | +------------------+ 1 row in set, 1 warning (0.00 sec) mysql> select * from account; +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 100.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) mysql> begin; --開(kāi)啟事務(wù) Query OK, 0 rows affected (0.00 sec) mysql> update account set blance=123.0 where id=1; --更新指定行 Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 --沒(méi)有commit哦!??! --終端B mysql> begin; mysql> select * from account; +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 123.00 | --讀到終端A更新但是未commit的數(shù)據(jù)[insert,delete同樣] | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec)
一個(gè)事務(wù)在執(zhí)行中,讀到另一個(gè)執(zhí)行中事務(wù)的更新(或其他操作)但是未commit的數(shù)據(jù),這種現(xiàn)象叫做臟讀(dirty read)
六、讀提交(不可重復(fù)讀)【Read Committed】
-- 終端A mysql> set global transaction isolation level read committed; Query OK, 0 rows affected (0.00 sec) --重啟客戶端 mysql> select * from account; --查看當(dāng)前數(shù)據(jù) +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 123.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) mysql> begin; --手動(dòng)開(kāi)啟事務(wù),同步的開(kāi)始終端B事務(wù) Query OK, 0 rows affected (0.00 sec) mysql> update account set blance=321.0 where id=1; --更新張三數(shù)據(jù) Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 --切換終端到終端B,查看數(shù)據(jù)。 mysql> commit; --commit提交! Query OK, 0 rows affected (0.01 sec) --切換終端到終端B,再次查看數(shù)據(jù)。 --終端B mysql> begin; --手動(dòng)開(kāi)啟事務(wù),和終端A一前一后 Query OK, 0 rows affected (0.00 sec) mysql> select * from account; --終端A commit之前,查看不到 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 123.00 | --老的值 | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) --終端A commit之后,看到了! --but,此時(shí)還在當(dāng)前事務(wù)中,并未commit,那么就造成了,同一個(gè)事務(wù)內(nèi),同樣的讀取,在不同的時(shí)間段(依舊還在事務(wù)操作中!),讀取到了不同的值,這種現(xiàn)象叫做不可重復(fù)讀(non reapeatable read)?。。ㄟ@個(gè)是問(wèn)題嗎??) mysql> select *from account; +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 321.00 | --新的值 | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec)
問(wèn)題:不可重復(fù)讀是問(wèn)題嗎??會(huì)造成什么后果??
比方說(shuō)小王要負(fù)責(zé)給tom把工資從3200改成4500.而小張要負(fù)責(zé)根據(jù)工資表篩選獎(jiǎng)品發(fā)放名單,在讀提交的情景下,當(dāng)小張運(yùn)行到中間的時(shí)候突然小王把修改的信息提交了,這個(gè)時(shí)候小張就有可能在員工表里看到兩個(gè)tom,這就會(huì)造成工作上的失誤??!
所以我們不應(yīng)該讓我們的用戶在實(shí)際操作的時(shí)候,兩個(gè)正在執(zhí)行的事物一方能夠讀到另一方的提交。所以雖然讀提交比讀未提交隔離級(jí)別高,但是我們也不推薦??!因?yàn)闀?huì)導(dǎo)致上述的不可重復(fù)讀的問(wèn)題??!
七、可重復(fù)讀【Repeatable Read】
mysql> select * from account; --終端A中事務(wù) commit之前,查看當(dāng)前表中數(shù)據(jù),數(shù)據(jù)未更新 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) mysql> select * from account; --終端A中事務(wù) commit 之后,查看當(dāng)前表中數(shù)據(jù),數(shù)據(jù)未更新 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) --可以看到,在終端B中,事務(wù)無(wú)論什么時(shí)候進(jìn)行查找,看到的結(jié)果都是一致的,這叫做可重復(fù)讀! mysql> commit; --結(jié)束事務(wù) Query OK, 0 rows affected (0.00 sec) mysql> select * from account; --再次查看,看到最新的更新數(shù)據(jù) +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec)
--如果將上面的終端A中的update操作,改成insert操作,會(huì)有什么問(wèn)題??
--終端A mysql> select *from account; +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) mysql> begin; --開(kāi)啟事務(wù),終端B同步開(kāi)啟 Query OK, 0 rows affected (0.00 sec) mysql> insert into account (id,name,blance) values(3, '王五', 5432.0); Query OK, 1 row affected (0.00 sec) --切換到終端B,查看另一個(gè)事務(wù)是否能看到 mysql> commit; --提交事務(wù) Query OK, 0 rows affected (0.00 sec) --切換終端到終端B,查看數(shù)據(jù)。 mysql> select * from account; +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | | 3 | 王五 | 5432.00 | +----+--------+----------+ 3 rows in set (0.00 sec) --終端B mysql> begin; --開(kāi)啟事務(wù) Query OK, 0 rows affected (0.00 sec) mysql> select * from account; --終端A commit前 查看 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) mysql> select * from account; --終端A commit后 查看 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec)
--多次查看,發(fā)現(xiàn)終端A在對(duì)應(yīng)事務(wù)中insert的數(shù)據(jù),在終端B的事務(wù)周期中,也沒(méi)有什么影響,也符合可重復(fù)的特點(diǎn)。但是,一般的數(shù)據(jù)庫(kù)在可重復(fù)讀情況的時(shí)候,無(wú)法屏蔽其他事務(wù)insert的數(shù)據(jù)(為什么?因?yàn)楦綦x性實(shí)現(xiàn)是對(duì)數(shù)據(jù)加鎖完成的,而insert待插入的數(shù)據(jù)因?yàn)椴⒉淮嬖?,那么一般加鎖無(wú)法屏蔽這類問(wèn)題),會(huì)造成雖然大部分內(nèi)容是可重復(fù)讀的,但是insert的數(shù)據(jù)在可重復(fù)讀情況被讀取出來(lái),導(dǎo)致多次查找時(shí),會(huì)多查找出來(lái)新的記錄,就如同產(chǎn)生了幻覺(jué)。這種現(xiàn)象,叫做幻讀(phantom read)。很明顯,MySQL在RR級(jí)別的時(shí)候,是解決了幻讀問(wèn)題的(解決的方式是用Next-Key鎖(GAP+行鎖)解決的。這塊比較難,可了解一下)。
mysql> select * from account; +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | +----+--------+----------+ 2 rows in set (0.00 sec) mysql> commit; --結(jié)束事務(wù) Query OK, 0 rows affected (0.00 sec) mysql> select * from account; --看到更新 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | | 3 | 王五 | 5432.00 | +----+--------+----------+ 3 rows in set (0.00 sec)
八、串行化【serializable】
--對(duì)所有操作全部加鎖,進(jìn)行串行化,不會(huì)有問(wèn)題,但是只要串行化,效率很低,幾乎完全不會(huì)被采用
--終端A mysql> set global transaction isolation level serializable; Query OK, 0 rows affected (0.00 sec) mysql> select @@tx_isolation; +----------------+ | @@tx_isolation | +----------------+ | SERIALIZABLE | +----------------+ 1 row in set, 1 warning (0.00 sec) mysql> begin; --開(kāi)啟事務(wù),終端B同步開(kāi)啟 Query OK, 0 rows affected (0.00 sec) mysql> select * from account; --兩個(gè)讀取不會(huì)串行化,共享鎖 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | | 3 | 王五 | 5432.00 | +----+--------+----------+ 3 rows in set (0.00 sec) mysql> update account set blance=1.00 where id=1; --終端A中有更新或者其他操作,會(huì)阻塞。直到終端B事務(wù) 提交。 Query OK, 1 row affected (18.19 sec) Rows matched: 1 Changed: 1 Warnings: 0 --終端B mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from account; --兩個(gè)讀取不會(huì)串行化 +----+--------+----------+ | id | name | blance | +----+--------+----------+ | 1 | 張三 | 4321.00 | | 2 | 李四 | 10000.00 | | 3 | 王五 | 5432.00 | +----+--------+----------+ 3 rows in set (0.00 sec) mysql> commit; --提交之后,終端A中的update才會(huì)提交。 Query OK, 0 rows affected (0.00 sec)
九、總結(jié)
其中隔離級(jí)別越嚴(yán)格,安全性越高,但數(shù)據(jù)庫(kù)的并發(fā)性能也就越低,往往需要在兩者之間找一個(gè)平衡點(diǎn)。(這個(gè)平衡點(diǎn)不是mysql決定而是由場(chǎng)景和需求決定的,所以mysql不是為我們指定隔離方式,而是給我們不同的隔離方案讓我們用戶根據(jù)實(shí)際場(chǎng)景需求做選擇)
臟讀(dirty read) 的重點(diǎn)是CUD:一個(gè)事務(wù)在執(zhí)行中,讀到另一個(gè)執(zhí)行中事務(wù)的更新(或其他操作)但是未commit的數(shù)據(jù)
不可重復(fù)讀的重點(diǎn)是U和D:同樣的條件, 你讀取過(guò)的數(shù)據(jù),再次讀取出來(lái)發(fā)現(xiàn)值不一樣了
幻讀的重點(diǎn)在于C:同樣的條件, 第1次和第2次讀出來(lái)的記錄數(shù)不一樣
說(shuō)明: mysql 默認(rèn)的隔離級(jí)別是可重復(fù)讀,一般情況下不要修改
上面的例子可以看出,事務(wù)也有長(zhǎng)短事務(wù)這樣的概念。事務(wù)間互相影響,指的是事務(wù)在并行執(zhí)行的時(shí)候,即都沒(méi)有commit的時(shí)候,影響會(huì)比較大
十、一致性(Consistency)
事務(wù)執(zhí)行的結(jié)果,必須使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài),變到另一個(gè)一致性狀態(tài)。當(dāng)數(shù)據(jù)庫(kù)只包含事務(wù)成功提交的結(jié)果時(shí),數(shù)據(jù)庫(kù)處于一致性狀態(tài)。如果系統(tǒng)運(yùn)行發(fā)生中斷,某個(gè)事務(wù)尚未完成而被迫中斷,而改未完成的事務(wù) 對(duì)數(shù)據(jù)庫(kù)所做的修改已被寫入數(shù)據(jù)庫(kù),此時(shí)數(shù)據(jù)庫(kù)就處于一種不正確(不一致)的狀態(tài)。因此一致性是通過(guò)原子性來(lái)保證的。
其實(shí)一致性并非技術(shù)層面的概念,而是和用戶的業(yè)務(wù)邏輯強(qiáng)相關(guān),一般MySQL提供技術(shù)支持,但是一致性還是要用戶業(yè)務(wù)邏輯做支撐,也就是,一致性,是由用戶決定的。(舉個(gè)例子,比方說(shuō)有個(gè)菜鳥(niǎo)程序員,對(duì)轉(zhuǎn)賬操作只在原賬戶減了錢,但是沒(méi)有在新賬戶加錢所以你用戶至少得保證你寫的mysql語(yǔ)句是對(duì)的、是完整的、業(yè)務(wù)邏輯是對(duì)的?。?!你能做到這些,那我就能保證你有一致性。但是你要是本身就有問(wèn)題,我mysql又不了解業(yè)務(wù),出錯(cuò)了關(guān)我什么事呢?所以一致性應(yīng)該由mysql和程序員共同完成,這才是對(duì)一致性正確的理解)
而技術(shù)上,通過(guò)A(原子性)I(隔離性)D(持久性)保證C(一致性) ,前者是因,后者是果
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
將MySQL的表數(shù)據(jù)全量導(dǎo)入clichhouse庫(kù)中
這篇文章主要介紹了將MySQL的表數(shù)據(jù)全量導(dǎo)入clichhouse庫(kù)中,詳細(xì)介紹全量導(dǎo)出MySQL數(shù)據(jù)到clickhouse表的相關(guān)內(nèi)容,需要的小伙伴可以參考一下2022-03-03MySQL可直接使用的查詢表的列信息(實(shí)現(xiàn)方案)
本文介紹了如何使用SQL快速將下劃線命名的表字段轉(zhuǎn)換為駝峰命名格式,包括確定下劃線位置、找到第一個(gè)字符、截取并拼接字符串等步驟,通過(guò)使用LOCATE、CONCAT、UCASE和LOWER等函數(shù),可以實(shí)現(xiàn)高效的字段命名轉(zhuǎn)換,感興趣的朋友跟隨小編一起看看吧2025-01-01Mysql建庫(kù)字符集和排序規(guī)則及說(shuō)明
這篇文章主要介紹了Mysql建庫(kù)字符集和排序規(guī)則及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12SQL UNION運(yùn)算符及其應(yīng)用場(chǎng)景深入探究
這篇文章主要為大家介紹了SQL UNION運(yùn)算符及其應(yīng)用場(chǎng)景示例深入探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12MySQL?原理與優(yōu)化之Limit?查詢優(yōu)化
這篇文章主要介紹了MySQL?原理與優(yōu)化之Limit?查詢優(yōu)化,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08MySQL與存儲(chǔ)過(guò)程的相關(guān)資料
這篇文章主要介紹了MySQL與存儲(chǔ)過(guò)程的相關(guān)資料,需要的朋友可以參考下2007-03-03