柚子快報邀請碼778899分享:MySQL —— 事務
柚子快報邀請碼778899分享:MySQL —— 事務
概念
事務把?組SQL語句打包成為?個整體,在這組SQL的執(zhí)行過程中,要么全部成功,要么全部失敗。 這組SQL語句可以是?條也可以是多條。
ACID 特性
原子性
Atomicity(原子性):一個事務中的所有操作,要么全部成功,要么全部失敗,不會出現(xiàn)只執(zhí)行了一半的情況。如果事務在執(zhí)行過程中發(fā)生錯誤,會回滾(Rollback )到事務開始前的狀態(tài),就像這個事務從來沒有執(zhí)行過一樣。
一致性
Consistency (一致性):在事務開始之前和事務結束以后,數(shù)據(jù)庫的完整性不會被破壞。這表示寫入的數(shù)據(jù)必須完全符合所有的預設規(guī)則,包括數(shù)據(jù)的精度、關聯(lián)性以及關于事務執(zhí)行過程中服務器崩潰后如何恢復。
以轉賬為例:兩個人之間相互轉賬,必須保證兩個人的總金額是不變的,這就是一致性。
隔離性
Isolation (隔離性):**數(shù)據(jù)庫允許多個并發(fā)事務同時對數(shù)據(jù)進行讀寫和修改,隔離性可以防止多個事務并發(fā)執(zhí)行時由于交叉執(zhí)行而導致數(shù)據(jù)的不一致。**事務可以指定不同的隔離級別,以權衡在不同的應用場景下數(shù)據(jù)庫性能和安全。
以轉賬為例:張三進行購物,同時李四也進行購物,兩人用于支付的銀行卡(假設有一千元)是一樣,假設兩個人同時輸入密碼,同時發(fā)起轉賬申請,這時候銀行那邊就是接收到兩個同時發(fā)生的事務,為了轉賬成功,兩個事務的執(zhí)行需要進行隔離,就是張三進行扣款100元之后,余額變?yōu)?00,之后執(zhí)行李四的扣款100元,余額變?yōu)?00,這就是隔離性。 如果沒有進行隔離,就是同時扣款100,最后余額會變成900。
持久性
Durability (持久性):事務處理結束后,對數(shù)據(jù)的修改將永久的寫入存儲介質,即便系統(tǒng)故障也不會丟失。
還是以轉賬為例:轉賬完成后,兩個人的最后的金額要永久保存起來。
事務的使用
事務具備的ACID特性,是我們使用事務的原因,在我們日常的業(yè)務場景中有大量的需求要用事務來保證。支持事務的數(shù)據(jù)庫能夠簡化我們的編程模型,不需要我們去考慮各種各樣的潛在錯誤和并發(fā)問題,在使用事務過程中,要么提交,要么回滾,不用去考慮網(wǎng)絡異常,服務器宕機等其他因素,因此我們經(jīng)常接觸的事務本質上是數(shù)據(jù)庫對 ACID 模型的?個實現(xiàn),是為應層用服務的。
要使用事務那么數(shù)據(jù)庫就要支持事務,在MySQL中支持事務的存儲引擎是InnoDB,可以通過show engines; 語句查看:
事務的語法:
# 開始一個新事務
start transaction;
# 或者
begin;
# 提交當前事務,并對更改持久化保存
commit;
# 回滾當前事務,取消其更改
rollback;
演示: 首先開啟事務,并查看當前的學生表
把最后一行的白糖修改為趙六:
我們進行事務的回滾,事務沒有進行提交,就不會進行數(shù)據(jù)的修改。
我們演示一下事務的提交: 開啟事務,進行更新操作(將錢七這個名字改成王五),進行事務提交。
保存點
在事務執(zhí)行的過程中設置保存點,回滾時指定保存點可以把數(shù)據(jù)恢復到保存點的狀態(tài)
語法:
# 設置保存點
savepoint point_name;
# 回滾到指定保存點
rollback to point_name;
演示: 開啟事務: 把王五這條記錄刪除,并且保存這個保存點
再次進行更新操作:
這時候突然發(fā)現(xiàn),更新操作失誤了,更新錯人了,我們可以回滾到保存點1:
自動 / 手動提交事務
默認情況下,MySQL是自動提交事務的,也就是說我們執(zhí)行的每個CRUD操作,,都會自動開啟?個事務并在語句執(zhí)行完成之后自動提交,發(fā)生異常時自動回滾。
我們來查看MySQL 事務提交是自動的還是手動的:
ON 表示是自動提交事務。
設置語法:
# 設置事務自動提交
set autocommit = 1; # 方式一
set autocommit = on; # 方式二
# 設置事務手動提交
set autocommi = 0; # 方式一
set autocommit = off; # 方式二
注意: 只要使用 START TRANSACTION 或 BEGIN 開啟事務,必須要通過 COMMIT 提交才會持久化,與是否設置 SET autocommit 無關。
手動提交模式下,不用顯示開啟事務,執(zhí)行修改操作后,提交或回滾事務時直接使用 commit 或 rollback
已提交的事務不能回滾
隔離級別
MySQL服務可以同時被多個客戶端訪問,每個客戶端執(zhí)行的DML語句以事務為基本單位,那么不同的客戶端在對同?張表中的同?條數(shù)據(jù)進行修改的時候就可能出現(xiàn)相互影響的情況,為了保證不同的事務之間在執(zhí)行的過程中不受影響,那么事務之間就需要要相互隔離,這種特性就是隔離性。
事務間不同程度的隔離,稱為事務的隔離級別;不同的隔離級別在性能和安全方面做了取舍,有的隔離級別注重并發(fā)性,優(yōu)點注重安全性,有的則是并發(fā)和安全始終,在MySQL的InnoDB 引擎中事務的隔離級別有四種: read uncommitted 讀未提交 read committed 讀已提交 repeatable read 可重復讀 (默認) serializable 串行化
查看隔離級別
事務的隔離級別分為全局作用域和會話作用域,查看不同作用域事務的隔離級別,可以使用以下的方式:
# 全局作用域
select @@global.transaction_isolation;
# 當前會話作用域
select @@session.transaction_isolation;
MySQL默認隔離級別為可重復讀
設置隔離級別 以及 不同隔離級別存在的問題
語法:
# 通過GLOBAL|SESSION分別指定不同作?域的事務隔離級別
SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL level|access_mode;
# 隔離級別
level: {
REPEATABLE READ # 可重復讀
| READ COMMITTED # 讀已提交
| READ UNCOMMITTED # 讀未提交
| SERIALIZABLE # 串?化
}
# 訪問模式
access_mode: {
READ WRITE # 表?事務可以對數(shù)據(jù)進?讀寫
| READ ONLY # 表?事務是只讀,不能對數(shù)據(jù)進?讀寫
}
# ?例
# 設置全局事務隔離級別為串?化,后續(xù)所有事務?效,不影響當前事務
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
# 設置會話事務隔離級別為串?化,當前會話后續(xù)的所有事務?效,不影響當前事務,可以在任何時候執(zhí)?
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
# 如果不指定任何作?域,設置只針對下?個事務,隨后的事務恢復之前的隔離級別
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
下面演示不同的隔離級別,會開啟兩個MySQL會話窗口。
讀未提交
先設置隔離級別:
開啟兩個事務: 查看我們的課程表: 當我們開啟事務進行修改操作的時候,發(fā)現(xiàn)事務還沒有提交,就已經(jīng)被人看到了事務未提交的內容,這種就叫做臟讀
臟讀就是讀取到別人未提交的事務內容。
讀已提交
設置隔離級別:
查看課程表:
開啟兩個事務:
現(xiàn)在我們進行修改操作,當沒有提交的時候,其他會話讀取的時候是讀不到未提交的內容。
當我們提交事務之后,其他會話才能讀到 ENGLISH 這條數(shù)據(jù)。
這時候有一個問題,就是一個會話已知進行修改與提交事務,另一個會話進行讀取數(shù)據(jù)的時候就會發(fā)現(xiàn)數(shù)據(jù)會一直變化,可是另一個會話并不想接收到修改的數(shù)據(jù)ENGLISH,只是想查看之前的數(shù)據(jù)(英文)的時候,就會特別煩惱。
這種問題我們稱為不可重復讀,不可重復讀指,讀取到了修改的數(shù)據(jù)。
可重復讀
設置隔離級別:
查看課程表:
首先開啟兩個事務:
其中一個事務將ENGLISH 修改未英文并提交事務,
另一個事務沒有受到上面事務的影響,還是讀取到的是ENGLISH
但是可重復讀有一個問題:就是如果事務進行插入、刪除操作的時候,影響的是結果集,在另一個事務在查詢的時候,結果集也會隨之發(fā)生改變。這種情況就叫做幻讀。
演示一下: 首先開始兩個事務,一個事務對課程表進行插入操作并且進行提交。
這時候另一個事務會話查看的時候發(fā)現(xiàn)多了一個結果,這就是幻讀。
刪除也是:
串行化
串行化就是最高程度的隔離級別。兩個事務都互不影響。
一個事務進行CRUD 操作的時候,不會影響到其他事務對同一個表的查詢,也就是串行化不存在臟讀,不可重復讀、幻讀的隔離問題。
小結
隔離級別臟讀不可重復讀幻讀read uncommitted存在存在存在read committed不存在存在存在repeatable read不存在不存在存在serializable不存在不存在不存在
從上到下并發(fā)性依次降低,隔離性依次提高。
柚子快報邀請碼778899分享:MySQL —— 事務
好文閱讀
本文內容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。