一:事務概念數據庫
- ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔離性、持久性)併發
二:事務產生的問題spa
- 多個事務同時執行的時候日誌
- 髒讀(dirty read)orm
- 不可重複讀(non-repeatable read)blog
- 幻讀(phantom read)的問題事務
- 爲了解決這些問題,就有了「隔離級別」的概念。 ci
三:隔離級別資源
- 首先隔離越高,效率就會越低。it
- 所以不少時候,咱們都要在兩者之間尋找一個平衡點。
- SQL 標準的事務隔離級別包括
- 讀未提交(read uncommitted)
- 讀提交(read committed)
- 可重複讀(repeatable read)
- 和串行化(serializable )
四:隔離級別的具體表現
- 在一個事務下
-
- 若隔離級別是「讀未提交」
- 則 V1 的值就是 2。這時候事務 B 雖然尚未提交,可是結果已經被 A 看到了。所以,V二、V3 也都是 2。
- 若隔離級別是「讀提交」
- 則 V1 是 1,V2 的值是 2。事務 B 的更新在提交後才能被 A 看到。因此, V3 的值也是 2。
- 若隔離級別是「可重複讀」
- 則 V一、V2 是 1,V3 是 2。之因此 V2 仍是 1,遵循的就是這個要求:事務在執行期間看到的數據先後必須是一致的。
- 若隔離級別是「串行化」
- 則在事務 B 執行「將 1 改爲 2」的時候,會被鎖住。直到事務 A 提交後,事務 B 才能夠繼續執行。因此從 A 的角度看, V一、V2 值是 1,V3 的值是 2。
五:隔離的實現
- 在 MySQL 中,實際上每條記錄在更新的時候都會同時記錄一條回滾操做。記錄上的最新值,經過回滾操做,均可以獲得前一個狀態的值。
- 假設一個值從 1 被按順序改爲了 二、三、4,在回滾日誌裏面就會有相似下面的記錄。
-
- 當前值是 4,可是在查詢這條記錄的時候,不一樣時刻啓動的事務會有不一樣的 read-view
- 同一條記錄在系統中能夠存在多個版本,就是數據庫的多版本併發控制(MVCC)。
- 在系統判斷沒有早於這個 read-view 的日誌,這個回滾日誌既會刪除。
六:長事務
- 長事務意味着系統裏面會存在很老的事務視圖。
- 因爲這些事務隨時可能訪問數據庫裏面的任何數據,因此這個事務提交以前,數據庫裏面它可能用到的回滾記錄都必須保留,這就會致使大量佔用存儲空間。
- 除了對回滾段的影響,長事務還佔用鎖資源,也可能拖垮整個庫。
七:如何監控和減小長事務的產生?
- 設置autocommit=1,另外,編寫一個定時監控Innodb_trx表中時間比較大的事務的任務
- 能夠在 information_schema 庫的 innodb_trx 這個表中查詢長事務,好比下面這個語句,用於查找持續時間超過 60s 的事務。
- select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60