數據庫事務是數據庫管理系統執行過程當中的一個邏輯單位,由一個有限的數據庫操做序列構成。但不是任意的數據庫操做序列都能成爲事務 對mysql常見的引擎有:MyISAM和InnoDB,MyISAM是默認高速的引擎並不支持事務功能,InnoDB支持行鎖定和事務處理,速度比MyISAM稍慢。 它的存在包含有如下兩個目的: 1.爲數據庫操做序列提供了一個從失敗中恢復到正常狀態的方法,同時提供了數據庫即便在異常狀態下仍能保持一致性的方法。 2.當多個應用程序在併發訪問數據庫時,能夠在這些應用程序之間提供一個隔離方法,以防止彼此的操做互相干擾。
READ_UNCOMMITTED:這是事務最低的隔離級別,它充許別外一個事務能夠看到這個事務未提交的數據,會出現髒讀、不可重複讀、幻讀 (隔離級別最低,併發性能高)mysql
READ_COMMITTED:保證一個事務修改的數據提交後才能被另一個事務讀取。另一個事務不能讀取該事務未提交的數據。能夠避免髒讀,但會出現不可重複讀、幻讀問題(鎖定正在讀取的行,mysql默認隔離級別)sql
REPEATABLE_READ:能夠防止髒讀、不可重複讀,但會出幻讀(鎖定所讀取的全部行)數據庫
SERIALIZABLE:這是花費最高代價可是最可靠的事務隔離級別,事務被處理爲順序執行。保證全部的狀況不會發生(鎖表,併發性及其低)併發
隔離級別 | 讀未提交 | 不可重複讀 | 幻讀 |
---|---|---|---|
READ UNCOMMITTED | 會 | 會 | 會 |
READ COMMITTED | 不 | 會 | 會 |
REPEATABLE READ | 不 | 不 | 會 |
SERIALIZABLE | 不 | 不 | 不 |
讀未提交:事務T2能讀取事務T1未提交的數據,當事務T1執行回滾時,T2讀取的數據就無效性能
不可重複讀:事務T2讀取事務T1未開啓時和T1提交後的數據不一致(主要是數據更新致使不一致)code
幻讀:事務T2讀取事務T1未開啓時和T1提交後的數據不一致(此時已鎖定T2讀取行,主要是插入和刪除數據致使不一致)對象
// 設置當前鏈接的事務隔離級別
SET SESSION TRANSACTION ISOLATION LEVEL 事務隔離級別;
//設置所有鏈接(包括新鏈接)的事務隔離級別
SET GLOBAL TRANSACTION ISOLATION LEVEL 事務隔離級別;索引
悲觀鎖:假設會發生併發衝突,迴避一切可能違反數據完整性的操做。進程
樂觀鎖:假設不會發生併發衝突,只在提交操做時檢查是否違反數據完整性,注意樂觀鎖並不能解決髒讀的問題。事務
在通常狀況下,悲觀鎖依靠數據庫的鎖機制實現,以保證操做最大程度的排他性和獨佔性,於是會致使數據庫性能的大量開銷和併發性很低,特別是對長事務而言,這種開銷每每過於巨大而沒法承受。爲了解決這樣的問題,樂觀鎖機制便出現了。樂觀鎖,大多狀況下是基於數據版本( Version )記錄機制實現。何謂數據版本?即爲數據增長一個版本標識,在基於數據庫表的版本解決方案中,通常是經過爲數據庫表增長一個 「version」 字段來實現。讀取出數據時,將此版本號一同讀出,以後更新時,對此版本號加一。此時,將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,若是提交的數據版本號大於數據庫表當前版本號,則給予更新,不然認爲是過時數據。ok~,關於悲觀鎖和樂觀鎖的簡單概念就先了解到這。
在mysql中,爲了保證數據一致性和防止數據處理衝突,引入了加鎖和解鎖的技術,這樣可使數據庫中特定的數據在使用時不讓其餘用戶(進程或事務)操做而爲該數據加鎖,直到該數據被處理完成後再進行解鎖。根據使用目的不一樣把鎖分爲共享鎖定(也稱爲讀取鎖定)和排他鎖定(寫入鎖定)。
共享鎖定:將對象數據變爲只讀形式的鎖定,這樣就容許多方同時讀取一個數據,此時數據將沒法修改。
排他鎖定:在對數據進行insert/update/delete時進行鎖定,在此時其餘用戶(進程或事務)一概不能讀取數據,從而也保證數據完整性。
經過上述的分析,咱們也理解了事務、鎖和隔離級別的概念,但鎖和事務以及分離水平關係如何呢?實際上,事務是解決多條sql執行執行過程的原子性、一致性、隔離性、持久性的總體解決方案,而事務分離水平則是併發控制的總體解決方案,其實際是綜合利用各類類型的鎖來解決併發問題。鎖是數據庫併發控制的內部基礎機制。對應用開發人員來講,只有當事務分離水平沒法解決併發問題和需求時,纔有必要在語句中手動設置鎖。關於鎖的鎖定,對於UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及數據集加排他鎖(X);對於普通SELECT語句,InnoDB不會加任何鎖,事務能夠經過如下語句顯示給記錄集加共享鎖或排他鎖。請注意InnoDB行鎖是經過給索引上的索引項加鎖來實現的,也就是說,只有經過索引條件檢索數據,InnoDB才使用行級鎖,不然,InnoDB將使用表鎖。