一、事務(wù)的概述
1.1 概念
保證事務(wù)中的所有操作都作為一個(gè)工作單元來執(zhí)行,即使出現(xiàn)了故障,都不能改變這種執(zhí)行方式。
當(dāng)在一個(gè)事務(wù)中執(zhí)行多個(gè)操作時(shí),要么所有的事務(wù)都被提交(commit),那么這些修改就永久地保存下來;要么數(shù)據(jù)庫(kù)管理系統(tǒng)將放棄所作的所有修改,整個(gè)事務(wù)回滾(rollback)到最初狀態(tài)。
1.2 事務(wù)的原理
事務(wù)開啟之后,所有的操作都會(huì)臨時(shí)保存到事務(wù)日志,事務(wù)日志只有在得到commit命令才會(huì)同步到數(shù)據(jù)庫(kù)表中,其他任何情況都會(huì)清空事務(wù)日志(rollback,斷開連接)。
1.3 事務(wù)的使用場(chǎng)景
如果在某個(gè)業(yè)務(wù)中需要執(zhí)行多條SQL語(yǔ)句,這種情況一般是需要使用到事務(wù),從而保證多條SQL語(yǔ)句執(zhí)行同時(shí)成功或同時(shí)失敗。
例如:轉(zhuǎn)賬、批量刪除、從購(gòu)物車中提交訂單等等操作。
1.4 事務(wù)的四大特性(ACID)
1. 原子性
原子性是指事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
2. 一致性
事務(wù)必須使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)。
3. 隔離性
事務(wù)的隔離性是指一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾,即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。
4. 持久性
持久性是指一個(gè)事務(wù)一旦被提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就是永久性的,接下來的其他操作和數(shù)據(jù)庫(kù)故障不應(yīng)該對(duì)其有任何影響。
二、MySQL進(jìn)行事務(wù)管理操作
2.1 自動(dòng)事務(wù)(MySQL默認(rèn))
MySQL默認(rèn)是自動(dòng)提交事務(wù)的,一條SQL語(yǔ)句就是一個(gè)事務(wù)。
2.2 開啟事務(wù)
2.2.1 方式一:手動(dòng)開啟事務(wù)
START TRANSACTION
手動(dòng)開啟事務(wù)之后,執(zhí)行的SQL語(yǔ)句都不會(huì)真正改變數(shù)據(jù)庫(kù)中的數(shù)據(jù),需要用戶手動(dòng)提交事務(wù)才能夠真正執(zhí)行SQL語(yǔ)句。
2.2.2 方式二:設(shè)置MySQL中的自動(dòng)提交參數(shù)
- 1、查看MySQL中事務(wù)是否自動(dòng)提交
show variables like '%commit%'
- 2、設(shè)置自動(dòng)提交的參數(shù)為OFF
set autocommit = 0
2.2.3 提交和回滾事務(wù)
1、提交事務(wù)
當(dāng)事務(wù)中的SQL語(yǔ)句執(zhí)行完畢之后,沒有出現(xiàn)任何問題,我們需要在最后提交事務(wù),讓這些SQL語(yǔ)句真正執(zhí)行去改變數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
commit
2、回滾事務(wù)
當(dāng)執(zhí)行這個(gè)事務(wù)中的SQL語(yǔ)句的過程中,一旦出現(xiàn)問題或者異常,則需要回滾事務(wù),從而回到SQL語(yǔ)句執(zhí)行之前的狀態(tài)。
rollback
三、事務(wù)的隔離級(jí)別
3.1 不考慮事務(wù)的隔離性會(huì)引發(fā)的問題
事務(wù)在操作時(shí)的理想狀態(tài)如下:
所有的事務(wù)之間保持隔離,互不影響。因?yàn)椴l(fā)操作,多個(gè)用戶同時(shí)訪問同一個(gè)數(shù)據(jù)。可能引發(fā)并發(fā)訪問的問題。
| 并發(fā)訪問的問題 | 含義 |
|---|---|
| 臟讀 | 一個(gè)事務(wù)讀取到了另一個(gè)事務(wù)中尚未提交的數(shù)據(jù) |
| 不可重復(fù)讀 | 一個(gè)事務(wù)中兩次讀取的數(shù)據(jù)內(nèi)容不一致,要求的是一個(gè)事務(wù)中多次讀取時(shí)數(shù)據(jù)是一致的,這是事務(wù)update時(shí)引發(fā)的問題 |
| 幻讀 | 一個(gè)事務(wù)中兩次讀取的數(shù)據(jù)的數(shù)量不一致,要求在一個(gè)事務(wù)多次讀取的數(shù)據(jù)的數(shù)量是一致的,這是insert或delete時(shí)引發(fā)的問題 |
3.2 事務(wù)隔離級(jí)別
| 級(jí)別 | 名字 | 隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 | 數(shù)據(jù)庫(kù)默認(rèn)隔離級(jí)別 |
|---|---|---|---|---|---|---|
| 1 | 讀未提交 | read uncommitted | 是 | 是 | 是 | |
| 2 | 讀已提交 | read committed | 否 | 是 | 是 | Oracle |
| 3 | 可重復(fù)度 | repeatable read | 否 | 否 | 是 | MySQL |
| 4 | 串行化 | serializable | 否 | 否 | 否 | 最高的隔離級(jí)別 |
隔離級(jí)別越高,性能(效率)越差,安全性越高。
3.2.1 設(shè)置隔離級(jí)別
- 設(shè)置事務(wù)隔離級(jí)別
set session transaction isolation level 隔離級(jí)別;
- 查詢當(dāng)前事務(wù)隔離級(jí)別
select @@tx_isolation