事務隔離:爲何你改了我還看不見

 

 

1  事務就是要保證一組數據庫的操做,要麼所有成功,要麼所有失敗。mysql中事務支持是在引擎層實現的。mysql是支持多引擎的mysql

2 隔離性和隔離級別sql

ACID Atomicity,Consistency,Isolation,Durability 原子性,一致性,隔離性,持久性數據庫

3當數據庫上存在多個事務同時執行時候,就可能出現髒讀,不可重複讀,幻讀的問題,爲了解決這些問題,就有了隔離級別的概念併發

讀未提交 。 一個事務尚未提交,它作的改變就能被別的事務看到框架

讀提交:一個事務提交以後,它作的變動纔會被其餘事務看到工具

可重複讀:一個事務在執行中看到的數據,老是和這個事務在啓動時看到的數據是一致的,這種隔離級別下,未提交的變動對其餘事務是不可見的測試

串行化:對於同一行記錄,寫會加寫鎖,讀會加讀鎖,當出現讀寫衝突的時候,後者訪問的事務必須等錢一個事務完成,纔可能繼續執行spa

 

4 事務隔離的實現線程

每條記錄在更新的時候都會同時記錄一條回滾操做,同一條記錄在系統中能夠存在多個版本,這就是數據庫的多版本併發控制MVCC日誌

 

4查看數據庫設置的隔離級別

show variables like 'transaction_isolation';

 

5  長事務意味着系統裏面會存在很老的事務視圖,因爲這些事務隨時可能訪問數據庫裏面的任何數據,因此這個事務提交以前,數據庫

裏面它可能用到的回滾記錄都必須保留,這就會致使大量佔用存儲空間,而且會佔用鎖資源

 

6事務的啓動方式

      1顯示啓動事務語句begin 或start transaction ,配置的提交語句是commit,回滾語句是rollback

      2 set autocommit=0,會關掉這個線程的自動提交,建議老是使用set autocommit=1,經過顯示語句來啓動事務

7能夠用以下語句查詢持續時間超過60s的事務

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

8如何避免出現長事務

     1  autocommit設置爲1,用文中提到的檢查長事務的方法作每秒的計劃任務檢查,檢查到的話記錄並殺死進程。

     2 另外,設置SET GLOBAL MAX_EXECUTION_TIME=3000. 確保單條語句執行時間在規定的範圍以內。

 

如何避免長事務

從開發者的角度:

1.確認是否使用了set autocommit=0,這個確認工做能夠在測試環境中開展

把mysql的general_log開起來,而後隨便跑一個業務邏輯

經過general_log的日誌來確認,通常框架若是會設置這個值,也會提供參數來控制行爲,你的目標就是把它改爲1

 

2確認是否有沒必要要的只讀事務,能夠從事務中去掉只讀事務

3業務鏈接數據庫的時候,根據業務自己的預估,經過set max_execution_time命令,來控制每一個語句執行的最長時間,避免單個語句意外執行太長時間

從數據端來看:

1 監控information_schema.innodb_trx表,設置長事務閥值,超長了就報警kill

2Percona的pt-kill工具

3.輸出全部的general_log,分析日誌行爲提早發現問題

4使用的是mysql5.6以上版本,把innodb_ubdo_tablespace設置爲2,若是出現大事務致使回滾段太大,這樣清理方便

相關文章
相關標籤/搜索