本篇文章給大家帶來的內容是關于MySQL事務相關知識的詳細介紹(代碼示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
MySQL事務以及事務隔離級別
MySQL事務主要用于處理操作量大,復雜度高的數據。比如在人員管理系統中,你刪除一個人員,你就要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等,這些數據庫操作語句就構成了一個事務(推薦課程:MySQL教程)
-
MySQL中只有使用了Innodb數據庫引擎的數據庫或表才支持事務
-
事務處理可以用來維護數據庫的完整性,保證成批的SQL語句要么全部執行,要么全部不執行
-
事務用來管理insert,update,delete語句
-
一般來說,事務必須滿足4個條件:原子性,一致性,隔離性,持久性
-
原子性:一個事務中所有操作,要么全部執行,要么全部不執行不會結束在中間某個環節。事務在執行過程中發生錯誤會被回滾到事務開始前的狀態
-
一致性:在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,包含資料的精確度,串聯性以及后續數據庫可以自發性的完成預定的工作
-
隔離性:數據庫允許多個并發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀取未提交內容,讀取提交內容,可重復讀和可串行化
-
持久化:事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失
在MySQL命令行的默認是設置下,事務都是自動提交的,即執行SQL語句后就會馬上執行COMMIT操作。因此要顯式的開啟一個事務需要使用命令BEGIN或START TRANSACTION,或者執行命令SET AUTOCOMMIT=0,用來禁止使用當前繪畫的自動提交
事務控制語句:
-
BEGIN或START TRANSACTION;顯式地開啟一個事務
-
COMMIT;也可以使用COMMIT WORK,二者等價的。COMMIT會提交事務,并使已對數據庫進行的所有修改成為永久性
-
ROLLBACK;也可以使用ROLLBACK WORK,二者等價。回滾會結束用戶的事務,并撤回正在進行的所有未提交的修改
-
SAVEPOINT identifier;SAVEPOINT允許在事務中創建一個保存點,一個事務可以有多個SAVEPOINT
-
RELESE SAVEPOINT identifier;刪除一個事務的保存點,當沒有指定的保存點時,執行該語句會拋出一個異常
-
ROLLBACK TO identified;把事務回滾到標記點
-
SET TRANSACTION;用來設置事務的隔離級別。InnoDB存儲引擎提供事務隔離級別有READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ和SERIALIZABLE
MySQL事務處理主要有兩種方法:
-
用BEGIN,ROLLBACK,COMMIT來實現
-
BEGIN開始一個事務
-
ROLLBACK事務回滾
-
COMMIT事務確認
直接SET來改變MySQL的自動提交模式:
-
SET AUTOCOMMIT=0禁止自動提交
-
SET AUTOCOMMIT=1開啟自動提交
事務四大特性之一:隔離性
-
事務A跟事務B之間具有一定的隔離性
-
read uncommited 讀未提交
-
在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用于實際應用。讀取未提交的數據稱為臟數據
read COMMIT
-
大多數數據庫系統的默認隔離級別(但不是MySQL)。一個事務只能看見已經提交事務所作的改變。其避免了臟讀,但仍然存在不可重復讀和幻讀問題
repeatable read
-
MySQL的默認級別;確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行。避免了臟讀和不可重復讀,但是會導致另一個問題:幻讀。幻讀是指用戶讀取某一個范圍的數據行時,另一個事務又在該范圍插入了新行,當用戶再讀取該范圍的數據行時,會發現新的幻影行。InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC)機制解決了該問題
-
可重復讀的隔離級別下使用了MVCC機制,select操作不會更新版本號,是快照讀(歷史版本);insert,update和delete會更新版本號,是當前讀(當前版本)
serializable
-
最高隔離級別,通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭
設置事務隔離級別
-
在my.cnf文件設置
-?READ-UNCOMMITTED -?READ-COMMITED -?REPEATABLE-READ -?SERIALIZABLE *?例如 [mysqlId] transaction-isolation?=?READ-COMMITTED
-
通過命令動態設置隔離級別
SET?[GLOBAL|SESSION]?TRANSACTION?ISOLATION?LEVEL?<isolation-level> 其中isolation-level可以是: -?READ?UNCOMMITTED -?READ?COMMITTED -?REPEATABLE?READ -?SERIALIZABLE GLOBAL|SESSION表示事務隔離級別的作用范圍: GLOBAL:表示對所有會話有效 SESSION:表示對當前會話有效</isolation-level>
事務并發問題
-
臟讀:事務A讀取了事務B更新的數據,然后B回滾操作,那么A讀取到的數據是臟數據
-
不可重復讀:事務A多次讀取到同一數據,事務B在事務A多次讀取過程中,對數據做了更新并未提交,導致事務A多次讀取同一條數據,結果不一致
-
幻讀:前后讀取的結果數據條數不一致。這是因為事務A的多次讀取過程中,事務B對表進行插入或刪除操作