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,若是出現大事務致使回滾段太大,這樣清理方便