事務是指對一組SQL
語句進行一個原子化的操做,即若是這一組SQL
語句中有一條發生錯誤,那麼其餘的同組SQL
就都不會被執行。數據庫
你能夠把它看成一個測試,當你執行完一組SQL
語句後,能夠查看一下結果是否正確,若是正確後能夠選擇提交,若是不正確則能夠進行回滾,恢復到本來的狀態。session
在MySQL
中,全部的操做默認都是自動進行提交,當開啓事務後則變爲手動提交。併發
單獨開啓是指對某一組的SQL
語句開啓事務。高併發
CREATE TABLE user( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, name CHAR(12) NOT NULL, balance INT UNSIGNED ); -- 建立用戶表 INSERT INTO user(name,balance) VALUES ("Yunya",1000), ("Ken",500); -- 插入數據 start transaction; -- 開啓事務,增刪改操做均要手動提交 UPDATE user SET balance = 500 WHERE name = "Yunya"; -- Yunya對Ken轉帳500 UPDATE user SET balance = 1000 WHERE name = "Ken"; SELECT * FROM user; -- 驗證是否出錯 COMMIT; -- 提交事務:手動提交上面兩條UPDATE -- ROLLBACK; -- 事務回滾:轉帳金額不對時使用回滾 BEGIN -- 關閉事務,增刪改操做均自動提交
若是全部SQL
都使用事務操做,咱們能夠經過 SET AUTOCOMMIT=0
關閉自動提交來開啓事務機制,這樣全部語句都是事務類型。測試
-- 關閉自動提交 SET AUTOCOMMIT = 0; INSERT INTO user(name,balance) VALUES ('Jack',8000); COMMIT; -- 開啓自動提交 SET AUTOCOMMIT = 1;
當高併發訪問會遇到多個事務的隔離問題,可能會出現如下:設計
- 髒讀:事務A讀取了事務B更新的數據,而後B回滾操做,那麼A讀取到的數據是髒數據
- 不可重複讀:事務A屢次讀取同一數據,事務B在事務A屢次讀取的過程當中,對數據做了更新並提交,致使事務A屢次讀取同一數據時,結果不一致。
- 幻讀:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。
不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住知足條件的行,解決幻讀須要鎖表code
系統默認隔離級別爲3級,可能出現幻讀的狀況。事務
隔離級別 | 中文釋義 | 髒讀 | 不可重複讀 | 幻讀 | 說明 |
---|---|---|---|---|---|
read uncommitted | 讀未提交 | 是 | 是 | 是 | 最低的事務隔離級別,一個事務還沒提交時,它作的變動就能被別的事務看到 |
read committed | 不可重複讀 | 否 | 是 | 是 | 保證一個事物提交後才能被另一個事務讀取。另一個事務不能讀取該事物未提交的數據 |
repeatable read | 可重複讀 | 否 | 否 | 是 | 屢次讀取同一範圍的數據會返回第一次查詢的快照,即便其餘事務對該數據作了更新修改。事務在執行期間看到的數據先後必須是一致的 |
serializable | 串行化 | 否 | 否 | 否 | 事務 100% 隔離,可避免髒讀、不可重複讀、幻讀的發生。花費最高代價但最可靠的事務隔離級別 |
通常來講系統默認的3級就足以應付大部分應用場景,可是設計金融類數據時必定要慎重。it
查詢隔離級別io
select @@tx_isolation;
設置隔離級別
set session transaction isolation level read uncommitted; -- set session只對當前會話有效,set global則對全局有效