MySQL的事務(wù)
簡(jiǎn)述:在關(guān)系數(shù)據(jù)庫(kù)中,事務(wù)可以是一條SQL語(yǔ)句、一組SQL語(yǔ)句或整個(gè)程序。注意事務(wù)和程序是兩個(gè)概念,一般來(lái)講,一個(gè)程序中包括多個(gè)事務(wù)
事務(wù)具有四個(gè)特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持續(xù)性(Durablity)。這四個(gè)特性簡(jiǎn)稱為ACID特性(ACID properties):
1.原子性:事務(wù)作為一個(gè)整體被執(zhí)行,包含在其中的對(duì)數(shù)據(jù)庫(kù)的操作要么全部執(zhí)行成功,要么全部失敗回滾,對(duì)于一個(gè)事務(wù)來(lái)說(shuō)不可能只執(zhí)行其中一部分操作,這就是事務(wù)的原子性。
2.一致性:事務(wù)應(yīng)確保數(shù)據(jù)庫(kù)的狀態(tài)從一個(gè)一致?tīng)顟B(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)一致?tīng)顟B(tài).
3.隔離性:多個(gè)事務(wù)并發(fā)執(zhí)行時(shí), 一個(gè)事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行.
4.持久性:已被提交的事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改應(yīng)該永久保存在數(shù)據(jù)庫(kù)中.
事務(wù)的隔離級(jí)別
1.讀未提交
在READUNCOMMITED 級(jí)別中, 事務(wù)的修改, 即使沒(méi)有提交, 對(duì)其他事務(wù)也是可見(jiàn)的. 其他事務(wù)可以讀取此事務(wù)中的未提交的數(shù)據(jù), 這也被稱為臟讀(DirtyRead). 此事務(wù)隔離級(jí)別會(huì)導(dǎo)致很多問(wèn)題, 并且性能也不會(huì)比其他事務(wù)隔離級(jí)別好多少, 因此在實(shí)際環(huán)境中很少使用.
2.讀提交
大多數(shù)的數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別都是READCOMMITED, 但是 MySQL 并不是. 在READCOMMITED 級(jí)別中, 一個(gè)事務(wù)從開(kāi)始到提交之前, 所做的任何修改對(duì)其他事務(wù)都是不可見(jiàn)的.
這個(gè)級(jí)別有時(shí)也叫不可重復(fù)讀(nonrepeatableread),因?yàn)閮纱螆?zhí)行同樣的查詢,可能會(huì)得到不一樣的結(jié)果。
3.可重復(fù)讀
REPEATABLEREAD解決了臟讀的問(wèn)題. 該級(jí)別保證了在同一個(gè)事務(wù)中多次讀取同樣記錄的結(jié)果時(shí)一致的. 但是理論上, 可重復(fù)讀隔離級(jí)別還是無(wú)法解決另一個(gè)幻讀(PhantomRead)的問(wèn)題. 所謂幻讀, 指的是當(dāng)某個(gè)事務(wù)在讀取某個(gè)范圍內(nèi)的記錄時(shí), 另外一個(gè)事務(wù)又在該范圍內(nèi)插入了新的記錄, 當(dāng)之前的事務(wù)再次讀取該范圍的記錄時(shí), 會(huì)產(chǎn)生幻行(PhantomRow).
可重復(fù)讀是 MySQL 的默認(rèn)事務(wù)隔離級(jí)別.
4.可串行化是最高的隔離級(jí)。它通過(guò)強(qiáng)制事務(wù)串行執(zhí)行,避免了前面說(shuō)的幻讀的問(wèn)題。簡(jiǎn)單來(lái)說(shuō),它會(huì)在讀取的每一行數(shù)據(jù)上都加鎖,所以可能導(dǎo)致大量的超時(shí)和鎖爭(zhēng)用的問(wèn)題。實(shí)際應(yīng)用中很少用到這個(gè)隔離級(jí)別,只有在非常需要確保數(shù)據(jù)的一致性而且可以接受沒(méi)有并發(fā)的情況下,才考慮使用該級(jí)別。
實(shí)例:
事務(wù)只對(duì)innodb 引擎適用?
showcreatetablet1;
altertablet1engine=innodb;#更改引擎?
deletefrom原來(lái)12條數(shù)據(jù)delete以后 再插入數(shù)據(jù) 從13開(kāi)始
truncate刪除 ? 原來(lái)12條數(shù)據(jù)delete以后 再插入數(shù)據(jù) 從1開(kāi)始
rollback回滾
mysql>insertintot1(name)values("user14"),("user24"),("user34"),("user44");
QueryOK,4rows affected (0.00sec)
Records:4Duplicates:0Warnings:0
mysql>savepointp3;#保持 插入后的一個(gè)狀態(tài)? 跟Linux的快照比較類似?
QueryOK,0rows affected (0.00sec)
mysql>deletefromt1;
QueryOK,24rows affected (0.00sec)
mysql>rollbacktop2;
QueryOK,0rows affected (0.00sec)
p1? p2? p3?
如果回到了 p2? 那么可以再回到? p1 ? ? 但是 回不到 P3了 ?