1、數(shù)據(jù)庫事務(wù)概述
事務(wù)是數(shù)據(jù)庫區(qū)別文件系統(tǒng)的重要特性之一,當(dāng)我們有了事務(wù)會(huì)讓數(shù)據(jù)庫始終保持一致性,同時(shí)我們還能通過事務(wù)的機(jī)制恢復(fù)到某個(gè)時(shí)間點(diǎn),這樣可以保證已提交到數(shù)據(jù)庫的修改不會(huì)因?yàn)橄到y(tǒng)的崩潰而丟失!
1.1 存儲(chǔ)引擎支持情況
SHOW ENGINES 命令來查看當(dāng)前 MySQL 支持的存儲(chǔ)引擎都有哪些,以及這些存儲(chǔ)引擎是否支持事務(wù)。
1.2 基本概念
**事務(wù):**一組邏輯操作單元,使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)。
1.3 事務(wù)的ACID屬性
- 原子性(atomicity)
- 一致性(consistency)
- 隔離型(isolation)
- 持久性(durability)
? redo undo日志
1.4 事務(wù)的狀態(tài)
我們現(xiàn)在知道 事務(wù) 是一個(gè)抽象的概念,它其實(shí)對(duì)應(yīng)著一個(gè)或多個(gè)數(shù)據(jù)庫操作,MySQL根據(jù)這些操作所執(zhí)
行的不同階段把 事務(wù) 大致劃分成幾個(gè)狀態(tài):
- 活動(dòng)的(active)
? 事務(wù)對(duì)應(yīng)的數(shù)據(jù)庫操作正在執(zhí)行過程中時(shí),我們就說該事務(wù)處在 活動(dòng)的 狀態(tài)。
- 部分提交的(partially committed)
? 當(dāng)事務(wù)中的最后一個(gè)操作執(zhí)行完成,但由于操作都在內(nèi)存中執(zhí)行,所造成的影響并 沒有刷新到磁盤
? 時(shí),我們就說該事務(wù)處在 部分提交的 狀態(tài)。
-
失敗的
當(dāng)事務(wù)處在 活動(dòng)的 或者 部分提交的 狀態(tài)時(shí),可能遇到了某些錯(cuò)誤(數(shù)據(jù)庫自身的錯(cuò)誤、操作系統(tǒng) 錯(cuò)誤或者直接斷電等)而無法繼續(xù)執(zhí)行,或者人為的停止當(dāng)前事務(wù)的執(zhí)行,我們就說該事務(wù)處在 失 敗的 狀態(tài)
-
中止的
如果事務(wù)執(zhí)行了一部分而變?yōu)?失敗的 狀態(tài),那么就需要把已經(jīng)修改的事務(wù)中的操作還原到事務(wù)執(zhí) 行前的狀態(tài)。換句話說,就是要撤銷失敗事務(wù)對(duì)當(dāng)前數(shù)據(jù)庫造成的影響。我們把這個(gè)撤銷的過程稱 之為 回滾 。當(dāng) 回滾 操作執(zhí)行完畢時(shí),也就是數(shù)據(jù)庫恢復(fù)到了執(zhí)行事務(wù)之前的狀態(tài),我們就說該事 務(wù)處在了 中止的 狀態(tài)。
-
提交的(committed)
? 當(dāng)一個(gè)處在 部分提交的 狀態(tài)的事務(wù)將修改過的數(shù)據(jù)都 同步到磁盤 上之后,我們就可以說該事務(wù)處
? 在了 提交的 狀態(tài)。
2、如何使用事務(wù)
2.1 顯式事務(wù)
-
開啟事務(wù)
START TRANSACTION 或者 BEGIN
START TRANSACTION 語句相較于 BEGIN 特別之處在于,后邊能跟隨幾個(gè) 修飾符 :
- READ ONLY :標(biāo)識(shí)當(dāng)前事務(wù)是一個(gè) 只讀事務(wù)
- READ WRITE :標(biāo)識(shí)當(dāng)前事務(wù)是一個(gè) 讀寫事務(wù)(默認(rèn))
- WITH CONSISTENT SNAPSHOT :啟動(dòng)一致性讀
-
一系列事務(wù)中的操作(主要是DML,不含DDL)
-
提交事務(wù) 或 中止事務(wù)(即回滾事務(wù))
- COMMIT 提交事務(wù)。當(dāng)提交事務(wù)后,對(duì)數(shù)據(jù)庫的修改是永久性的。
- ROLLBACK 回滾事務(wù)。即撤銷正在進(jìn)行的所有沒有提交的修改
- ROLLBACK TO [SAVEPOINT] 將事務(wù)回滾到某個(gè)保存點(diǎn)。
2.2 隱式事務(wù)
MySQL中有一個(gè)系統(tǒng)變量 autocommit :SHOW VARIABLES LIKE ‘a(chǎn)utocommit’;
如果我們想關(guān)閉這種 自動(dòng)提交 的功能,可以使用下邊兩種方法之一:
- 把系統(tǒng)變量 autocommit 的值設(shè)置為 OFF -> SET autocommit = OFF;
- 顯式的的使用 START TRANSACTION 或者 BEGIN 語句開啟一個(gè)事務(wù)。這樣在本次事務(wù)提交或者回滾前會(huì)暫時(shí)關(guān)閉掉自動(dòng)提交的功能。
2.3 隱式提交數(shù)據(jù)的情況
-
數(shù)據(jù)定義語言(Data Definition langurage,縮寫為DDL)
-
隱式使用或修改mysql數(shù)據(jù)庫中的表
-
事務(wù)控制或關(guān)于鎖定的語句
2.4 使用舉例:提交和回滾
2.5 使用舉例:測試不支持事務(wù)的 Engine
MyISAM 不支持事務(wù)
2.6 使用舉例: savepoint
3、事務(wù)的隔離級(jí)別
MySQL是一個(gè) 客戶端/服務(wù)器 架構(gòu)的軟件,對(duì)于同一個(gè)服務(wù)器來說,可以有若干個(gè)客戶端與之連接,每
個(gè)客戶端與服務(wù)器連接上之后,就可以稱為一個(gè)會(huì)話( Session )。每個(gè)客戶端都可以在自己的會(huì)話中
向服務(wù)器發(fā)出請(qǐng)求語句,一個(gè)請(qǐng)求語句可能是某個(gè)事務(wù)的一部分,也就是對(duì)于服務(wù)器來說可能同時(shí)處理
多個(gè)事務(wù)。事務(wù)有 隔離性 的特性,理論上在某個(gè)事務(wù) 對(duì)某個(gè)數(shù)據(jù)進(jìn)行訪問 時(shí),其他事務(wù)應(yīng)該進(jìn)行 排
隊(duì) ,當(dāng)該事務(wù)提交之后,其他事務(wù)才可以繼續(xù)訪問這個(gè)數(shù)據(jù)。但是這樣對(duì) 性能影響太大 ,我們既想保持
事務(wù)的隔離性,又想讓服務(wù)器在處理訪問同一數(shù)據(jù)的多個(gè)事務(wù)時(shí) 性能盡量高些 ,那就看二者如何權(quán)衡取
舍了。
3.1 數(shù)據(jù)并發(fā)問題
針對(duì)事務(wù)的隔離性和并發(fā)性,我們?cè)趺醋鋈∩崮??先看一下訪問相同數(shù)據(jù)的事務(wù)在不保證串行執(zhí)行的情況下可能會(huì)出現(xiàn)哪些問題:
1、臟寫
修改另一個(gè)事務(wù)未提交的數(shù)據(jù)
2、臟讀
讀另一個(gè)事務(wù)未提交的數(shù)據(jù)
3、不可重復(fù)讀
4、幻讀
對(duì)于兩個(gè)事務(wù)Session A、Session B, Session A 從一個(gè)表中 讀取 了一個(gè)字段, 然后 Session B 在該表中 插
入 了一些新的行。 之后, 如果 Session A 再次讀取 同一個(gè)表, 就會(huì)多出幾行。那就意味著發(fā)生了幻讀。
3.2 SQL中的四種隔離級(jí)別
我們?cè)敢馍釛壱徊糠指綦x性來換取一部分性能在這里就體現(xiàn)在:設(shè)立一些隔離級(jí)別,隔離級(jí)別越低,并發(fā)問題發(fā)生的就越多。 SQL標(biāo)準(zhǔn) 中設(shè)立了4個(gè) 隔離級(jí)別 :
-
READ UNCOMMITTED :讀未提交,在該隔離級(jí)別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。不能避免臟讀、不可重復(fù)讀、幻讀。
-
READ COMMITTED :讀已提交,它滿足了隔離的簡單定義:一個(gè)事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變。這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級(jí)別(但不是MySQL默認(rèn)的)??梢员苊馀K讀,但不可重復(fù)讀、幻讀問題仍然存在。
-
REPEATABLE READ :可重復(fù)讀,事務(wù)A在讀到一條數(shù)據(jù)之后,此時(shí)事務(wù)B對(duì)該數(shù)據(jù)進(jìn)行了修改并提交,那么事務(wù)A再讀該數(shù)據(jù),讀到的還是原來的內(nèi)容。可以避免臟讀、不可重復(fù)讀,但幻讀問題仍然存在。這是MySQL的默認(rèn)隔離級(jí)別。
-
SERIALIZABLE :可串行化,確保事務(wù)可以從一個(gè)表中讀取相同的行。在這個(gè)事務(wù)持續(xù)期間,禁止其他事務(wù)對(duì)該表執(zhí)行插入、更新和刪除操作。所有的并發(fā)問題都可以避免,但性能十分低下。能避免臟讀、不可重復(fù)讀和幻讀。
3.3 MySQL支持的四種隔離級(jí)別
MySQL的默認(rèn)隔離級(jí)別為REPEATABLE READ,我們可以手動(dòng)修改一下事務(wù)的隔離級(jí)別。
# 查看隔離級(jí)別,MySQL 5.7.20的版本之前
SHOW VARIABLES LIKE 'tx_isolation';
# 查看隔離級(jí)別,MySQL 5.7.20的版本及之后
SHOW VARIABLES LIKE 'transaction_isolation';
3.4 如何設(shè)置事務(wù)的隔離級(jí)別
SET [GLOBAL|SESSION] TRANSACTION_ISOLATION = '隔離級(jí)別'
#其中,隔離級(jí)別格式:
> READ-UNCOMMITTED
> READ-COMMITTED
> REPEATABLE-READ
> SERIALIZABLE
4、事務(wù)的分類
可以把事務(wù)分為以下幾種類型:
扁平事務(wù)(Flat Transactions)
帶有保存點(diǎn)的扁平事務(wù)(Flat Transactions with Savepoints)
鏈?zhǔn)聞?wù)(Chained Transactions)
嵌套事務(wù)(Nested Transactions)文章來源:http://www.zghlxwxcb.cn/news/detail-442582.html
分布式事務(wù)(Distributed Transactions)文章來源地址http://www.zghlxwxcb.cn/news/detail-442582.html
到了這里,關(guān)于高級(jí)篇十三、事務(wù)基礎(chǔ)知識(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!