事務是啥
MySQL的事務就是把多個sql語句操作打包在一起執行,要么全部執行,要么一個都別執行。這種操作稱為“原子性”,是事務最核心的特征。當某個sql操作出錯時,就會進行“回滾/rollback”操作,即把執行過的操作逆向恢復回去,數據庫會把每個操作記錄下來,當某個操作出錯時,就會把之前的操作進行逆操作,比如前面是刪除操作,逆操作就進行插入操作,把刪除的數據重新插入回去。
start transaction;--開啟事務
--
--中間寫多個sql
--
commit;--提交事務
當開啟事務后不會立即執行sql操作,會等到commit提交事務后,會統一執行多個sql。
事務的四大特性
-
原子性:即把多個sql操作合并在一起(相當于一個操作),統一執行,要么都執行成功,要么一個都別執行。
-
一致性:即事務執行前后,數據都是合法的。
-
持久性:即事務的操作后的結果都會寫入硬盤,無論是程序還是主機重啟,修改操作都是生效的。
-
隔離性:即同一個數據庫服務器,在針對多個事務并發執行時,事務之間相互影響的程度。隔離性越高,并發程度越低,執行效率越慢,反之隔離性越低,并發越高,效率越快。隔離性分為四個檔位,分別是:
read uncommited 讀未提交
:這個檔位MySQL不做任何限制,隔離性最低,并發程度最高,執行效率最快,此時存在“臟讀、不可重復讀、幻讀”問題。像博客文章點贊數量這種操作就可以使用這個檔位,因為不管點贊是重復了還是沒點贊成功,問題都不大,效率快就行。read commited 讀已提交
:這個檔位是針對“寫操作”加鎖,此時隔離性提高,并發程度降低,執行效率降低,此時解決了”臟讀“問題,存在”不可重復讀、幻讀“問題。repeatable read 可重復讀
:Mysql的默認檔位,此時針對“寫操作”和“讀操作”都進行加鎖,此時隔離性進一步提高,并發程度進一步降低,此時解決了“臟讀、不可重復讀”,依舊存在“幻讀”問題。serializable 串行化
:這個檔位是嚴格執行串行化的,即放棄并發,隔離性最高,執行效率最慢,解決了“臟讀、不可重復讀、幻讀”問題。
臟讀:即一個事務讀了一個臟數據,比如此時有兩個事務針對同一份數據進行操作。事務A在讀數據,事務B在往這份數據里寫東西,當事務A讀完之后走了,事務B把這份數據修改并保存提交了,此時事務A之前讀到的數據就變成了無效數據,這種情況就稱為“臟讀”,于是可以進行”寫操作“加鎖,即在“寫操作”時,事務A不能讀數據。
不可重復讀:即針對”寫操作“進行加鎖的情況下,依舊是兩個事務針對同一份數據進行操作,在事務B針對這份數據進行”寫操作“時,事務A是不能進行”寫操作”的,但是可以讀這份文件。于是事務A在讀同一份數據時,事務B隨即修改了數據,導致事務A讀了一半發現數據變了,這種情況就稱為“不可重復讀”問題,即同一個事務針對一份文件連續讀兩次的結果不一致,于是需要針對”讀操作“進行加鎖。
幻讀:在“寫操作”和“讀操作”都進行加鎖的情況下,事務A進行讀數據(文件)時,事務B不能針對同一份文件進行“讀寫”操作,不過事務B可以針對其他文件進行操作,比如增加一個文件,或者刪除一個文件,于是當事務A讀完一個文件后,發現文件的數量變了,這種情況就稱為“幻讀”問題。即同一個事務連續兩次讀的結果集不同,于是需要嚴格執行串行化,即放棄并發。
栗子:
【臟讀】比如學校黑板報,同學A早上10點來看黑板報發現自己考試成績第一名,高興的回到寢室;隨后10:30學生B過來把黑板報給改了,漏了一名同學的成績,此時同學A真實排名是第三名,不過同學A依舊以為自己是第一名,這種情況就屬于是“臟讀問題”。【不可重復讀】同學A在讀第一塊黑板報,同學B緊接把黑板報的內容改了,導致同學A此時發現讀的內容已經變了,這種情況就屬于是”不可重復讀“,不可重復讀是同學A能立馬發現內容變了,而臟讀是同學A不能發現內容變了。【幻讀】同學A此時在讀黑板報,目前只有一個黑板報有內容,當同學A讀完這個黑板報后就應該算是讀完了黑板報,但是當同學A讀完之后,發現旁邊幾塊黑板報被同學B都寫上了內容,此時導致同學A發現不再是只有一塊黑板報有內容,而是有好幾塊,這種情況就是“幻讀”。