MySQL的事務(wù)特性概念梳理總結(jié)
重溫事務(wù)的概念
為什么用事務(wù)、事務(wù)是什么
我們規(guī)定了,做一件事情,只有成功和失敗!
用個很經(jīng)典的例子舉例:銀行轉(zhuǎn)賬
,A向B轉(zhuǎn)賬十萬,能不能發(fā)生一遍付錢一邊沒收錢的情況?
現(xiàn)實中一定是A和B同時成功或者失敗,不能出現(xiàn)一邊成功另一邊失敗的情景,這就是事務(wù)的簡單例子。
那么由這個例子我們想想事務(wù)其實是為了保證什么?
假如:
- 張三問羅老師借錢,借了錢沒寫借據(jù)。
- 這是做了事情,但是沒有依據(jù),就算做成功了,也沒辦法證明。突出借據(jù)的重要性(持久性) redolog
- 張三問羅老師借錢,羅老師同意了,可是張三不想借了。
這是事情做成功了,關(guān)鍵點在于,我可不可以反悔。(張三去決定)突出回滾的重要性(原子性)undo log
所以**事務(wù)其實就是想要做的事情是一個整體!**事務(wù)的存在目的就是為了事情能夠正確成功的執(zhí)行。
如果以數(shù)據(jù)庫的角度去看:
在關(guān)系型數(shù)據(jù)庫中,事務(wù)其實就是【一組原子性的SQL】或者說一個獨立不可分割的工作單元,如果數(shù)據(jù)庫引擎能成功的對數(shù)據(jù)庫引用該組查詢的全部語句,那么就執(zhí)行該組查詢,如果其中有任何一條語句因為崩潰或者其他原因無法執(zhí)行,那么所有的語句都不會執(zhí)行,也就是說,事務(wù)內(nèi)的語句,要么全部執(zhí)行成功,要么全部執(zhí)行失敗。
那么剛才那個轉(zhuǎn)賬的例子,讓我們?nèi)懸粋€事務(wù),應(yīng)該怎么寫?
查詢A賬戶的余額是否大于10W塊錢從A賬戶余額中減去10W塊錢在B賬戶余額中增加10W塊錢
怎么用事務(wù)
還記得怎么寫事務(wù)的sql語句嗎?
--開啟一個事務(wù) BEGIN;--等價于 START TRANSACTION; --執(zhí)行我們需要的SQL --提交事務(wù) COMMIT; --回滾事務(wù) ROLLBACK;
我們來模擬一下A的兩個賬戶(CMBC銀行、ICBC銀行)之間轉(zhuǎn)賬的事務(wù)
# 開啟轉(zhuǎn)賬事務(wù) BEGIN; SELECT BALANCE FROM BANK_CMBC WHERE USER_NAME = 'A的CMBC銀行賬戶'; # 這里需要判斷余額 是否大于等于 10W UPDATE BANK_CMBC SET BALANCE = BALANCE - 100000 WHERE USER'A的CMBC銀行賬戶'; UPDATE BANK_ICBC SET BALANCE = BALANCE + 100000 WHERE USER'A的ICBC銀行賬戶'; # 這里當然還需要記錄 記錄表 日志表 轉(zhuǎn)賬記錄表 等 SELECT * FROM BANK_CMBC; SELECT * FROM BANK_ICBC; --提交 COMMIT; --或者回滾 ROLLBACK; # BANK_CMBC 里的余額會減去10W 然后 BANK_ICBC賬戶增加10W, # 這個就是我們事務(wù)的具體使用場景了,要么全部成功要么全部失敗!
我能不能只提交一部分事務(wù),一部分事務(wù)不提交呢?
也可以,使用SAVEPOINT
,但是呢,要記得提交。
BEGIN; SELECT BALANCE FROM BANK_CMBC WHERE USER_NAME = 'A的CMBC銀行賬戶'; # 這里需要判斷余額 是否大于等于 10W UPDATE BANK_CMBC SET BALANCE = BALANCE - 100000 WHERE USER_NAME ='A的CMBC銀行賬戶'; SAVEPOINT A;--設(shè)置回滾點 UPDATE BANK_ICBC SET BALANCE = BALANCE + 100000 WHERE USER_NAME ='A的ICBC銀行賬戶'; # 這里當然還需要記錄 記錄表 日志表 轉(zhuǎn)賬記錄表 等 # 回滾到保存點 ROLLBACK TO A; SELECT * FROM BANK_CMBC; SELECT * FROM BANK_ICBC; COMMIT;
# 這個時候我們的記錄是多少? # 我們看一下 在SAVEPOINT 之前的語句都能正確提交,SAVEPOINT之后的語句因為我們手動回滾了他們是沒有被更改成的,這 # 就是SAVEPOINT的作用,他能夠在一個事務(wù)里開啟一個嵌套事務(wù)。主事務(wù)和嵌套事務(wù)屬于同一個事務(wù),嵌套事務(wù)出錯回滾不會影響主事務(wù),主事務(wù)回滾會將嵌套事務(wù)一起回滾。主事務(wù)提交嵌套事務(wù)也會跟著提交。
問一個面試官可能會問到的問題,我們知道多條SQL語句開啟的時候,能保證全部成功、或者全部失敗。那么單條SQL語句有沒有事務(wù)呢?
其實每個語句都是原子性的,他們被隱式的加入了 BEGIN
; START TRANSACTION
開啟事務(wù),并COMMIT
;
就好像:
BEGIN; UPDATE BANK CMBC SET BALANCE = BALANCE + 100000 WHERE USER_NAME = 'A的CMBC銀行賬戶'; COMMIT; # 如果在語句執(zhí)行期間發(fā)生錯誤,則會回滾該語句。 # 但是如果每個語句都這么寫,挺麻煩的。所以在事務(wù)里有一個概念叫做自動提交設(shè)置! # 我們每個單語句都會自動提交的,可以自行關(guān)閉自動提交!默認是開啟的,這個也區(qū)別于全局global和會話session
show session VARIABLES like 'autocommit'; --查詢自動開啟提交 show global variables like 'autocommit'; --查詢自動開啟提交 set SESSION autocommit=0; --關(guān)閉自動提交
總結(jié):數(shù)據(jù)庫的事務(wù)都是為了解決這種業(yè)務(wù)場景出現(xiàn)的一門技術(shù),為了保證多個SQL語句,要么全部執(zhí)行成功,要么全部執(zhí)行失敗。
事務(wù)的四大特性是什么?
原子性
一個事務(wù)必須被視為一個不可分割的最小單元,整個事務(wù)中的操作要么全部提交成功,要么全部失敗回滾,對于一個事務(wù)來說,不可能只執(zhí)行其中的一部分操作。
一致性
數(shù)據(jù)庫總是由一個一致性狀態(tài)轉(zhuǎn)換到另外一個一致性狀態(tài)。在前面的例子中,一致性確保了,即使在執(zhí)行第三條第四條預(yù)計之間系統(tǒng)崩潰了,CMBC賬戶中也不會損失10W,要不然A要哭死,如果是系統(tǒng)崩潰最終事務(wù)沒有提交,所有事務(wù)中所作的修改也不會保存到數(shù)據(jù)庫中。
持久性
俗話說就是保證及時落盤;
持久性是為了保證斷點等異常的情況,還能保證我們commit的數(shù)據(jù)不丟失!并且不會回滾!
不會出現(xiàn)我commit之后,重啟后又被回滾了!
剛才寫了有個undolog能保證原子性,同樣的,也有個redolog(重做日志)去保證特殊情況的數(shù)據(jù)丟失!
redolog會記錄每次事務(wù)的執(zhí)行語句!當發(fā)生斷電等比較不可控的因素后,能根據(jù)redolog進行數(shù)據(jù)恢復(fù)?。?!
隔離性
一個事務(wù)所作的修改在最終提交之前,對其他事務(wù)是不可見的。在前面的例子中,我們執(zhí)行完第三條語句,第四條語句還沒成功執(zhí)行的時候,事務(wù)尚未提交。這個時候去看我們ACMBC中的賬號還有10W,如果這個時候去取錢是不可以的,要等待事務(wù)提交了才可以。
剛才我們所看到的,是不是都是一個人或者說是一個線程的問題?
假如我們有很高的并發(fā)量,如果有多個事務(wù)同時操作同一條數(shù)據(jù),會導(dǎo)致什么?
事務(wù)因并發(fā)出現(xiàn)的問題有哪些?可以查看另一篇文章
鏈接:
到此這篇關(guān)于MySQL的事務(wù)特性概念梳理總結(jié)的文章就介紹到這了,更多相關(guān)MySQL事務(wù)內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。