MySQL事物(详解并发问题和隔离级别)(小白也能懂哦)
1.事物的概念
2.事物的四大特性(ACID)
3.事物的創建
4.事物的并發問題和解決
5.回滾點
6.事物的適用模式
1.事物的概念
事物由單獨單元的一個或者多個SQL語句組成,在這個單元中,每個SQL語句是相互依賴的,而整個單獨單元作為一個不可分割的整體,如果單元中某條SQL語句一旦執行失敗或產生錯誤,整個單元將會回滾,所有受到影響的數據將返回到事物開始以前的狀態,如果單元中的所有SQL語句均執行成功,則事物將會順利執行
用事物舉個例子:
假如小明要給小紅轉賬1000元,這個轉賬會涉及到兩個關鍵操作就是:將小明的余額減少1000元,將小紅的余額增加1000元。萬一在這兩個操作之間突然出現錯誤比如銀行系統崩潰,導致小明余額減少而小紅的余額沒有增加,這樣就不對了。事務就是保證這兩個關鍵操作要么都成功,要么都要失敗。
2.事物的四大特性(ACID)
用一些比較規范的語言解釋:
1.原子性: 事務是最小的執行單位,不允許分割。事務的原子性確保動作要么全部完成,要么完全不起作用;
2.一致性: 執行事務前后,數據保持一致,多個事務對同一個數據讀取的結果是相同的;
3.隔離性: 并發訪問數據庫時,一個用戶的事務不被其他事務所干擾,各并發事務之間數據庫是獨立的;
4.持久性: 一個事務被提交之后。它對數據庫中數據的改變是持久的,即使數據庫發生故障也不應該對其有任何影響。
用大白話解釋:
1.原子性(A):一個事物不可分割,要么都執行要么都不執行
2.一致性(C ):一個事物執行會使數據從一個狀態切換到另一個狀態
3.隔離性(I):一個事物的執行不會受另一個事物的干擾
4.持久性(D):一個事物一旦提交則會永久改變數據庫的數據
3.事物的創建
3.1關于事物的提交方式
MySQL數據庫中事物默認自動提交
什么意思呢,就是一條DML(增刪改)語句會自動提交一次事物(事物里邊的內容只能包含增刪查改),我們在對表中的數據進行增刪改等操作的時候,表中的數據會做出相應的永久性更改,也就是說我們想要永久更改表中的數據就必須提交事物,增刪改是默認的自動提交,所以我們每次運行我們的SQL語句就會永久性更改
我們可以查看事物的默認提交:
語句:
select @@autocommit
可以看到默認值是1,也就是默認自動提交
我們修改默認自動提交為默認手動提交
語句:
set @@autocommit=0
3.2事物的手動提交步驟
手動提交的三個操作
1.開啟事物:start transaction(可寫也可不寫)
2.回滾:rollback:回到事物開啟前的狀態
3.提交:commit:運行SQL語句并且永久更改SQL語句里邊的內容
我們拿一個student表來說:
注意:
想要手動提交事物必須先更改事物的默認提交方式
我們舉一個例子,我們修改所有同學的性別都為男,再修改所有同學的年齡都為20
語句:
set @@autocommit=0;
start transaction(可寫也可不寫)
update student set ssex=“男”
update student set age=20
commit(或者rollback);
當我們使用rollback的時候就會回滾,不會對表中的數據進行更改,相當于時光倒流到開啟事物的那一步,但是我們提交后就會永久性更改
4.事物的并發問題和解決
4.1事物的并發問題
對于同時運行的多個事物訪問數據庫中相同的元素,如果沒有采取必要的隔離機制就會導致并發問題
并發問題分為以下三個:
1.臟讀:對于兩個事物a,b,a讀取了已經被b更新單但還沒有提交的字段,之后若b回滾,那么a讀取的內容就是臨時的無效的不正確的
2.不可重復讀:對于兩個事物a,b,a讀取一個字段然后b更新了該字段之后a再讀取同一字段值就不同了
3.幻讀:對于事物a,b,a從一個表中讀取一個字段,然后b在表里插入一些新的行,a再讀的時候就會多出來幾行
我們舉一個臟讀的例子,其他的兩種就不再演示了
首先我們有一個表為student
我們先把隔離級別調最低(因為此時才會發生臟讀)為READ-UNCOMMITTED,然后我們用事物把翠花的性別改成男,但是不提交事物
再打開另一個cmd命令行,然后查詢(當然這個cmd窗口的隔離級別也要設置成READ-UNCOMMITTED):
我們會發現翠花的性別已經更改,但是如果此時我們在第一個cmd命令行輸入回滾,那么第二個命令行此時查看的翠花的性別是臨時的,不是正確的
我們再用第二個命令行查看就會發現其實翠花的性別和第一次查詢有所不同,所以第一次我我們讀到的數據是臟數據,也就是臟讀
4.2事物并發問題的解決:
我們可以設置隔離級別來避免并發問題的出現
隔離級別的種類(由低到高依次介紹):
1.READ-UNCOMMITTED(讀取未提交): 最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致臟讀、幻讀或不可重復讀。
2.READ-COMMITTED(讀取已提交): 允許讀取并發事務已經提交的數據,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發生。
3.REPEATABLE-READ(可重復讀): 對同一字段的多次讀取結果都是一致的,除非數據是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發生。
4.SERIALIZABLE(可串行化): 最高的隔離級別,完全服從ACID的隔離級別。所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。
各種隔離級別可以導致的并發問題:
對于上圖也就是說×就可以避免此類型的并發問題
1.MySQL默認的隔離級別REPEATABLE_READ,可以用 select @@tx_isolation來查看
2.我們可以用set session transaction isolation level + 隔離級別來設置隔離級別
5.回滾點
關鍵字savepaint
例子:
set autocommit=0;
update 表 set sex=‘女’ where id =2;
savepaint a;
update 表 set sname=‘李白’ where id =3;
rollback to a;
這里的a是回滾點名字,這里從后往前回滾所以update 表 set sex=‘女’ where id =2;這條指令就不會恢復,到回滾點就會停下。這里還要注意回滾點只能和rollback連用
還有一個注意點:delete和truncate在事物使用使用時的區別
在事物中delete在事物回滾時可以恢復刪除的內容,但是truncate在回滾后不會恢復
6.事物的適用模式
了解存儲引擎
在MySQL中的數據用各種不同的技術存儲在文件或者內存中,在MySQL中用的最多的存儲引擎有innodb,myisam,memory等,其中innodb支持事物,myisam,memory不支持事物
通過下面這個命令查看數據庫支持的存儲引擎
show engines
總結
以上是生活随笔為你收集整理的MySQL事物(详解并发问题和隔离级别)(小白也能懂哦)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL视图附带例子详解(小白都能懂哦
- 下一篇: MySQL变量,存储过程,函数,流程控制