數據庫事物

1.事物定義

所謂事務,它是一個操做序列,這些操做要麼都執行,要麼都不執行,它是一個不可分割的工做單位。mysql

2.ACID

ACID,是指在可靠數據庫管理系統(DBMS)中,事務(transaction)所應該具備的四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。sql

原子性

原子性是指事務是一個不可再分割的工做單位,事務中的操做要麼都發生,要麼都不發生。數據庫

一致性

一致性是指在事務開始以前和事務結束之後,數據庫的完整性約束沒有被破壞。這是說數據庫事務不能破壞關係數據的完整性以及業務邏輯上的一致性。安全

隔離性

多個事務併發訪問時,事務之間是隔離的,一個事務不該該影響其它事務運行效果。併發

這指的是在併發環境中,當不一樣的事務同時操縱相同的數據時,每一個事務都有各自的完整數據空間。由併發事務所作的修改必須與任何其餘併發事務所作的修改隔離。工具

並行處理時可能出現問題:性能

髒讀:事務A修改了一個數據,但未提交,事務B讀到了事務A未提交的更新結果,若是事務A提交失敗,事務B讀到的就是髒數據。

不可重複讀:在同一個事務中,對於同一份數據讀取到的結果不一致。好比,事務B在事務A提交前讀到的結果,和提交後讀到的結果可能不一樣。

幻讀:在一個事務內讀取到了別的事務插入的數據,致使先後讀取不一致。

mysql定義了四種事物的隔離級別:spa

Read Uncommitted:最低的隔離級別,什麼都不須要作,一個事務能夠讀到另外一個事務未提交的結果。全部的併發事務問題都會發生。

Read Committed:只有在事務提交後,其更新結果纔會被其餘事務看見。能夠解決髒讀問題。

Repeated Read:在一個事務中,對於同一份數據的讀取結果老是相同的,不管是否有其餘事務對這份數據進行操做,以及這個事務是否提交。能夠解決髒讀、不可重複讀。

Serialization:事務串行化執行,隔離級別最高,犧牲了系統的併發性。能夠解決併發事務的全部問題。
  1. Serializable(串行化):可避免髒讀、不可重複讀、幻讀狀況的發生。
  2. Repeatable read(可重複讀):可避免髒讀、不可重複讀狀況的發生。
  3. Read committed(讀已提交):可避免髒讀狀況發生。
  4. Read uncommitted(讀未提交):最低級別,以上狀況均沒法保證。

持久性

持久性,意味着在事務完成之後,該事務所對數據庫所做的更改便持久的保存在數據庫之中,並不會被回滾。線程

即便出現了任何事故好比斷電等,事務一旦提交,則持久化保存在數據庫中。code

mysql數據庫事物

mysql數據庫默認的事務隔離級別是:Repeatable read(可重複讀)。

mysql數據庫引擎

對於MySQL來講,最具備表明性的表存儲引擎就是InnoDB和MyISAM。二者之間最主要的區別就是是否進行外鍵的數據完整性檢查。對於InnoDB存儲引擎能夠經過外鍵來進行數據完整性檢查,對於MyISAM存儲引擎須要開發人員在程序級進行數據關聯保證數據完整性。

MyISAM:這個是默認類型,它是基於傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫,它是存儲記錄和文件的標準方法。與其餘存儲引擎比較,MyISAM具備檢查和修復表格的大多數工具。 MyISAM表格能夠被壓縮,並且它們支持全文搜索。它們不是事務安全的,並且也不支持外鍵。若是事物回滾將形成不徹底回滾,不具備原子性。若是執行大量的SELECT,MyISAM是更好的選擇。

InnoDB:這種類型是事務安全的。它與BDB類型具備相同的特性,它們還支持外鍵。InnoDB表格速度很快。具備比BDB還豐富的特性,所以若是須要一個事務安全的存儲引擎,建議使用它。若是你的數據執行大量的INSERT或UPDATE,出於性能方面的考慮,應該使用InnoDB表,對於支持事物的InnoDB類型的表,影響速度的主要緣由是AUTOCOMMIT默認設置是打開的,並且程序沒有顯式調用BEGIN開始事務,致使每插入一條都自動Commit,嚴重影響了速度。能夠在執行SQL前調用BEGIN,多條SQL造成一個事物(即便AUTOCOMMIT打開也能夠),將大大提升性能。

併發狀況下加鎖

InnoDB實現瞭如下兩種類型的行鎖

  • 共享鎖:容許一個事務去讀一行,容許其餘事物得到改行的共享鎖,可是阻止其餘事務得到改行數據的排他鎖。
  • 排他鎖:容許獲取排他鎖的事務更新數據,阻止其餘事務取得相同的數據集共享讀鎖和排他寫鎖。

事務能夠經過如下語句顯示給記錄集加共享鎖或排鎖

共享鎖:SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE。

排他鎖:SELECT * FROM table_name WHERE ... FOR UPDATE。

注意:用SELECT .. IN SHARE MODE得到共享鎖,主要用在須要數據依存關係時確認某行記錄是否存在,並確保沒有人對這個記錄進行UPDATE或者DELETE操做。可是若是當前事務也須要對該記錄進行更新操做,則頗有可能形成死鎖,對於鎖定行記錄後須要進行更新操做的應用,應該使用SELECT ... FOR UPDATE方式獲取排他鎖。

InnoDB行鎖是經過索引上的索引項來實現的,這一點MySQL與Oracle不一樣,後者是經過在數據中對相應數據行加鎖來實現的。InnoDB這種行鎖實現特色意味者:只有經過索引條件檢索數據,InnoDB纔會使用行級鎖,不然,InnoDB將使用表鎖!

MyISAM提供鎖模式主要有表共享鎖(Table Read Lock)和表獨佔寫鎖(Table Write Lock)

  • 對MyISAM的讀操做,不會阻塞其餘用戶對同一表讀請求,但會阻塞對同一表的寫請求;
  • 對MyISAM的寫操做,則會阻塞其餘用戶對同一表的讀和寫操做;
  • MyISAM表的讀操做和寫操做之間,以及寫操做之間是串行的。

當一個線程得到對一個表的寫鎖後,只有持有鎖線程能夠對錶進行更新操做。其餘線程的讀、寫操做都會等待,直到鎖被釋放爲止。

MyISAM在執行查詢語句(SELECT)前,會自動給涉及的全部表加讀鎖,在執行更新操做(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖,這個過程並不須要用戶干預,所以用戶通常不須要直接用LOCK TABLE命令給MyISAM表顯式加鎖。

併發鎖

在必定條件下,MyISAM也支持查詢和插入的併發進行,MyISAM存儲引擎有一個系統變量concurrent_insert,專門用以控制其併發插入的行爲,其值分別能夠爲0、1或2。

  • 當concurrent_insert設置爲0時,不容許併發插入。
  • 當concurrent_insert設置爲1時,若是MyISAM容許在一個讀表的同時,另外一個進程從表尾插入記錄。這也是MySQL的默認設置。
  • 當concurrent_insert設置爲2時,不管MyISAM表中有沒有空洞,都容許在表尾插入記錄,都容許在表尾併發插入記錄。
相關文章
相關標籤/搜索