當多個用戶訪問同一份數(shù)據(jù)時,一個用戶在更改數(shù)據(jù)的過程中,可能有其他用戶同時發(fā)起更改請求,為保證數(shù)據(jù)庫記錄的更新從一個一致性狀態(tài)變?yōu)榱硗庖粋€一致性狀態(tài),使用事務處理是非常必要的,事務具有以下四個特性:
創(chuàng)新互聯(lián)建站主要從事成都網站建設、做網站、網頁設計、企業(yè)做網站、公司建網站等業(yè)務。立足成都服務松嶺,十載網站建設經驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:18982081108
MySQL 提供了多種事務型存儲引擎,如 InnoDB 和 BDB 等,而 MyISAM 不支持事務。為了支持事務,InnoDB 存儲引擎引入了與事務處理相關的 REDO 日志和 UNDO 日志,同時事務依賴于 MySQL 提供的鎖機制
事務執(zhí)行時需要將執(zhí)行的事務日志寫入日志文件,對應的文件為 REDO 日志。當每條 SQL 進行數(shù)據(jù)更新操作時,首先將 REDO 日志寫進日志緩沖區(qū)。當客戶端執(zhí)行 COMMIT 命令提交時,日志緩沖區(qū)的內容將被刷新到磁盤,日志緩沖區(qū)的刷新方式或者時間間隔可以通過參數(shù) innodb_flush_log_at_trx_commit 控制
REDO 日志對應磁盤上的 ib_logifleN 文件,該文件默認為 5MB,建議設置為 512MB,以便容納較大的事務。MySQL 崩潰恢復時會重新執(zhí)行 REDO 日志的記錄,恢復最新數(shù)據(jù),保證已提交事務的持久性
與 REDO 日志相反,UNDO 日志主要用于事務異常時的數(shù)據(jù)回滾,具體內容就是記錄數(shù)據(jù)被修改前的信息到 UNDO 緩沖區(qū),然后在合適的時間將內容刷新到磁盤
假如由于系統(tǒng)錯誤或者 rollback 操作而導致事務回滾,可以根據(jù) undo 日志回滾到沒修改前的狀態(tài),保證未提交事務的原子性
與 REDO 日志不同的是,磁盤上不存在單獨的 UNDO 日志文件,所有的 UNDO 日志均存在表空間對應的 .ibd 數(shù)據(jù)文件中,即使 MySQL 服務啟動了獨立表空間
在 MySQL 中,可以使用 BEGIN 開始事務,使用 COMMIT 結束事務,中間可以使用 ROLLBACK 回滾事務。MySQL 通過 SET AUTOCOMMIT、START TRANSACTION、COMMIT 和 ROLLBACK 等語句支持本地事務
MySQL 定義了四種隔離級別,指定事務中哪些數(shù)據(jù)改變其他事務可見、哪些數(shù)據(jù)該表其他事務不可見。低級別的隔離級別可以支持更高的并發(fā)處理,同時占用的系統(tǒng)資源更少
InnoDB 系統(tǒng)級事務隔離級別可以使用以下語句設置:
查看系統(tǒng)級事務隔離級別:
InnoDB 會話級事務隔離級別可以使用以下語句設置:
查看會話級事務隔離級別:
在該隔離級別,所有事務都可以看到其他未提交事務的執(zhí)行結果。讀取未提交的數(shù)據(jù)稱為臟讀(Dirty Read),即是:首先開啟 A 和 B 兩個事務,在 B 事務更新但未提交之前,A 事務讀取到了更新后的數(shù)據(jù),但由于 B 事務回滾,導致 A 事務出現(xiàn)了臟讀現(xiàn)象
所有事務只能看見已經提交事務所做的改變,此級別可以解決臟讀,但也會導致不可重復讀(Nonrepeatable Read):首先開啟 A 和 B 兩個事務,A事務讀取了 B 事務的數(shù)據(jù),在 B 事務更新并提交后,A 事務又讀取到了更新后的數(shù)據(jù),此時就出現(xiàn)了同一 A 事務中的查詢出現(xiàn)了不同的查詢結果
MySQL 默認的事務隔離級別,能確保同一事務的多個實例在并發(fā)讀取數(shù)據(jù)時看到同樣的數(shù)據(jù)行,理論上會導致一個問題,幻讀(Phontom Read)。例如,第一個事務對一個表中的數(shù)據(jù)做了修改,這種修改會涉及表中的全部數(shù)據(jù)行,同時第二個事務也修改這個表中的數(shù)據(jù),這次的修改是向表中插入一行新數(shù)據(jù),此時就會發(fā)生操作第一個事務的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行
InnoDB 通過多版本并發(fā)控制機制(MVCC)解決了該問題:InnoDB 通過為每個數(shù)據(jù)行增加兩個隱含值的方式來實現(xiàn),這兩個隱含值記錄了行的創(chuàng)建時間、過期時間以及每一行存儲時間發(fā)生時的系統(tǒng)版本號,每個查詢根據(jù)事務的版本號來查詢結果
通過強制事務排序,使其不可能相互沖突,從而解決幻讀問題。簡而言之,就是在每個讀的數(shù)據(jù)行上加上共享鎖實現(xiàn),這個級別會導致大量的超時現(xiàn)象和鎖競爭,一般不推薦使用
為了解決數(shù)據(jù)庫并發(fā)控制問題,如走到同一時刻客戶端對同一張表做更新或者查詢操作,需要對并發(fā)操作進行控制,因此產生了鎖
共享鎖的粒度是行或者元組(多個行),一個事務獲取了共享鎖以后,可以對鎖定范圍內的數(shù)據(jù)執(zhí)行讀操作
排他鎖的粒度與共享鎖相同,一個事務獲取排他鎖以后,可以對鎖定范圍內的數(shù)據(jù)執(zhí)行寫操作
有兩個事務 A 和 B,如果事務 A 獲取了一個元組的共享鎖,事務 B 還可以立即獲取這個元組的共享鎖,但不能獲取這個元組的排他鎖,必須等到事務 A 釋放共享鎖之后。如果事務 A 獲取了一個元組的排他鎖,事務 B 不能立即獲取這個元組的共享鎖,也不能立即獲取這個元組的排他鎖,必須等到 A 釋放排他鎖之后
意向鎖是一種表鎖,鎖定的粒度是整張表,分為意向共享鎖和意向排他鎖。意向共享鎖表示一個事務有意對數(shù)據(jù)上共享鎖或者排他鎖。有意表示事務想執(zhí)行操作但還沒真正執(zhí)行
鎖的粒度主要分為表鎖和行鎖
表鎖的開銷最小,同時允許的并發(fā)量也是最小。MyISAM 存儲引擎使用該鎖機制。當要寫入數(shù)據(jù)時,整個表記錄被鎖,此時其他讀/寫動作一律等待。一些特定的動作,如 ALTER TABLE 執(zhí)行時使用的也是表鎖
行鎖可以支持最大的并發(fā),InnoDB 存儲引擎使用該鎖機制。如果要支持并發(fā)讀/寫,建議采用 InnoDB 存儲引擎
首先一點, 如果你是 mysql 5.5 肯定支持事務
其次, 是否可以用事務, 取決于你使用的表的存儲引擎.
默認 myIsam 是不支持事務的
你要把表轉換成 Innodb 存儲引擎才可以使用事務
你怎么知道你的不支持呢,
你來做個試驗好了。
打開是事務請鍵入:
set @@AUTOCOMMIT=0;
BEGIN WORK;
然后你去把你MySQL的某一張表中的數(shù)據(jù)刪除
然后再打:ROLLBACK WORK;
你就驚訝的發(fā)現(xiàn),你剛才刪的數(shù)據(jù)還原了
回滾事物:SAVEPOINT id
id是保存點的名稱
結束事物:COMMIT
具體還是要一本書才行。網絡上的其實說實話太雜了
最后補充一下, 修改存儲引擎的 MYSQL 語句:
alter table 表名 type = InnoDB;
MySQL 事務
什么是事務?
MySQL 事務主要用于處理操作量大,復雜度高的數(shù)據(jù)。比如說,在人員管理系統(tǒng)中,你刪除一個人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數(shù)據(jù)庫操作語句就構成一個事務!
在 MySQL 中只有使用了 Innodb 數(shù)據(jù)庫引擎的數(shù)據(jù)庫或表才支持事務。
事務處理可以用來維護數(shù)據(jù)庫的完整性,保證成批的 SQL 語句要么全部執(zhí)行,要么全部不執(zhí)行。
事務用來管理 insert,update,delete 語句
一般來說,事務是必須滿足4個條件(ACID):原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。
原子性:一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環(huán)節(jié)。事務在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務開始前的狀態(tài),就像這個事務從來沒有執(zhí)行過一樣。
一致性:在事務開始之前和事務結束以后,數(shù)據(jù)庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規(guī)則,這包含資料的精確度、串聯(lián)性以及后續(xù)數(shù)據(jù)庫可以自發(fā)性地完成預定的工作。
隔離性:數(shù)據(jù)庫允許多個并發(fā)事務同時對其數(shù)據(jù)進行讀寫和修改的能力,隔離性可以防止多個事務并發(fā)執(zhí)行時由于交叉執(zhí)行而導致數(shù)據(jù)的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
持久性:事務處理結束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。
在 MySQL 命令行的默認設置下,事務都是自動提交的,即執(zhí)行 SQL 語句后就會馬上執(zhí)行 COMMIT 操作。因此要顯式地開啟一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執(zhí)行命令 SET AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。
from 樹懶學堂 - 一站式數(shù)據(jù)知識平臺