在 mysql 中,事務支援是在引擎層實現的。mysql是乙個支援多引擎的系統,但並不是所有的引擎都支援事務,比如mysql原生的myisam引擎就不支援事務,這也是myisam被innodb取代的重要原因之一。
事務acid:原子性、一致性、隔離性、永續性。(atomicity、consistency、isolation、durability)。
多個事務同時執行的時候,會可能出現髒讀、不可重複讀和幻讀等問題。所以,事務中引入隔離性,但是,隔離得越嚴重,效率越低下,我們必須在兩者之間找到乙個平衡點。因此,sql標準的隔離級別:
隔離級別:讀未提交、讀提交、可重複讀和序列化。隔離級別由mysql啟動時候的引數決定:transaction-isolation
讀未提交:乙個事務還未提交,它所做的變更就能被別的事務看到。
讀提交:乙個事務提交後,它所做的變更才能被其他的事務看到。
可重複讀:乙個事務執行期間所看到的資料,總是跟這個事務在啟動時候看到的資料是一致的。
序列化:對於同一條記錄,寫會加「寫鎖」,讀會加「讀鎖」。當出現讀寫鎖衝突的時候,後訪問的事務必須等待前面的事務執行完成,它才可以繼續執行。
如圖所示,在不同隔離級別下面,下圖事務執行的結果不一樣。
不同隔離級別下,資料庫行為是有所不同的。oracle資料庫的預設隔離級別是「讀提交」,因此,對於一些從oracle遷移到mysql的應用,為保證資料庫隔離級別的一致,要把mysql的隔離級別設定為「讀提交」。
同一條記錄在系統中可以存在多個版本,就是資料庫的多版本併發控制(mvcc)。
盡量不要使用長事務,長事務意味著系統裡面會存在很老的事務檢視,在事務提交之前,事務檢視用到的回滾記錄都必須保留,占用大量的儲存空間。
下面這個語句,用於查詢持續時間超過 60s 的事務。
select * from information_schema.innodb_trx where
time_to_sec(timediff(now(),trx_started))>60
在mysql中,每一條更新語句都會產生一條回滾操作記錄,一條記錄上的最新值,通過回滾操作,都可以得到前乙個狀態的值。
例如,一條記錄把值1修改為2,3,4後,在回滾日誌裡面就會有如下記錄:
回滾日誌如果一直保留著,會占用大量的記憶體,系統會判斷,不需要它的時候,就會自動刪除。判斷的標準是系統裡面沒有比這個回滾日誌更早的read-view的時候,就會刪除它。
顯式啟動事務:begin或者start transation,提交語句是commit,回滾語句是rollback。
建議使用這個語句set autocommit=1來啟動事務。
建議使用commit work and chain 語法。
alter table a engine=innodb
mysql事務隔離最高 Mysql事務隔離級別
mysql官方文件顯示 innodb中每個隔離級別的詳細描述如下 read uncommitted select語句以非鎖定方式被執行,但是乙個可能更早期版本的記錄會被用到。因此,使用這個隔離級別,比如,讀是不連貫的。著也被稱為 髒讀 dirty read 另外,這個隔離級別象read commit...
MySQL 事務隔離
未提交讀 read uncommitted 允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料 提交讀 read committed 只能讀取到已經提交的資料。oracle等多數資料庫預設都是該級別 不重複讀 可重複讀 repeated read 可重複讀。在同乙個事務內的查詢都是事務開始時刻...
Mysql 事務隔離
1 事務的特性 原子性 一致性 隔離性 永續性 2 多事務同時執行的時候,可能會出現的問題 髒讀 不可重複讀 幻讀 3 事務隔離級別 讀未提交 讀提交 可重複讀 序列化 4 不同事務隔離級別的區別 讀未提交 乙個事務還未提交,它所做的變更就可以被別的事務看到 讀提交 乙個事務提交之後,它所做的變更才...