MyISAM引擎不支持事務。
隔離型與隔離級別
事務分為:A(Atomicity,原子性)C(Consistency,一致性)I(Isolation,隔離性)D(Durability,持久性)。
當數據庫上多個事務同時執行的時候,就可能癡線臟讀、不可重復讀、幻讀的問題,為了解決這些問題,需要使用到隔離級別的概念。
SQL標準的事務隔離級別包括:讀未提交(read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(serializable)。
- 讀未提交:一個事務還沒提交時,它做的變更就能被別的事務看到。
- 讀提交:一個事務提交之后,它做的變更才能被其他事務看到。
- 可重復讀:一個事務執行過程中看到的數據,總是跟這個事務在啟動是看到的數據是一致的。當然在可重復讀隔離級別下,為提交事務變更對其他事務是不可見的。
- 串行化:對于同一行記錄,寫會加寫鎖,讀會加讀鎖。當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行。
在實際情況中,數據庫里面會創建一個視圖,訪問的時候以視圖的邏輯結果為準。在可重復讀隔離級別下,
這個事務是在事務啟動的時候創建,整個事務存在期間都用這個視圖;在讀提交隔離級別下,這個視圖是在每個sql語句開始執行的時候創建的;
讀未提交隔離級別下直接返回記錄最新值,沒有視圖概念;串行化隔離級別下直接用加鎖的方式來避免并行訪問。
Oracle數據默認隔離級別是讀提交。
事務隔離的實現
在MySQL中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值,通過回滾操作,都可以得到前一個狀態的值。
不同時刻啟動的事務會有不同的read-view,同一條記錄在系統中可以存在多個版本,這就是數據庫的多版本并發控制。
在沒有事務再需要用到這些回滾日志時,回滾日志會被刪除。當系統里沒有比這個回滾日志更早的read-view的時候。
為什么不建議使用長事務?
長事務意味著存在很老的事務視圖。由于這些事務隨時可能訪問數據庫里面的任何數據,所以這個事務提交之前,數據庫里面它可能用到的回滾記錄都必須保留,
這樣會導致大量占用存儲空間。并且長事務還占用鎖資源,也可能會拖垮整個庫。
事務的啟動方式
MySQL的事務啟動方式如下:
- 顯示啟動事務語句,begin 或 start transaction.配套的提交語句是commit,回滾語句是rollback。
- set autocommit=0.線程的自動提交關閉。這個事務持續存在知道你主動提交commit或者rollback語句,或者斷開鏈接。
有些客戶端默認關閉自動提交,需要顯示設置 set autocommit=1。
為了減少頻繁提交事務的時間,可以使用commit work and chain,在提交事務并啟動下一個事務。