mysql之事務和鎖

併發控制:
    MVCC 多版本併發控制。
        用戶在操做時操做的是帶有時間點的快照。而不是表自己。最後將快照進行合併。

鎖:
    讀鎖:共享鎖。讀取操做不會對用戶之間產生影響。
    寫鎖:獨佔鎖。一個用戶寫入時,其餘用戶就不能寫入。
    能夠手動設置:
        LOCK TABLES TBNAME [AS AILAS] LOCK_TYPE,... 給表加鎖
            LOCK_TYPE
                READ 讀鎖
                WRITE 寫鎖

        UNLOCK TABLES 解除全部表的鎖,注意不能指定TBNAME。

    鎖力度:
        表鎖:鎖定整張表
        頁鎖:鎖定頁塊,一個頁塊中包含多個行。
        行鎖:鎖定行

        mysql服務器僅支持表鎖,行鎖須要存儲引擎支持。每一個引擎對鎖的策略都不一樣。

        力度越精細越能提升併發,越粗糙越能方便管理。

    實例:
        1.給tutors表建立讀鎖:
            mysql>LOCK TABLES tutors read;

        2.解鎖:
            mysql>UNLOCK TABLES;

事務:
    事務就是將多個涉及到大量的cpu操做和io操做的多個操做看作一組。這樣的組被稱做事務。

    事務的流程:
        啓動(START TANSACTION)-->寫入撤銷日誌中 --> 執行操做(一堆SQL語句)|執行過程當中斷後根據撤銷日誌回滾(ROLLBACK)--> 寫入重作日誌中-->  根據重作日誌進行磁盤操做 (提交COMMINT)

    多事務併發:
        例如進行io操做時cpu空閒,能夠利用cpu進行新的事務,這是多事務併發的基本思想。可是多事務併發有可能形成事物之間進行交互。因此此時要使用隔離機制保證數據庫的一致性。
        依賴的技術手段:
            鎖
            時間戳
            多版本和快照隔離

    多事務交互:
        經過io產生的數據集,事務之間就能夠進行交互。可是數據集是實時變更的。因此這種交互會產生不一致狀態。在這種狀態下,交互的結果可能產生差錯

        髒讀:
            一個事務未提交前,另外一個事務進行讀取操做。讀操未提交的內容稱爲髒讀。
        幻讀:
            一個事務對某個表執行查詢操做時,另外一個事務對此表進行修改,會形成先後查詢不一致。

    事務的狀態:
        活動的:正在執行的。
        部分提交的:執行完成,可是最後一條語句正在提交中。
        失敗的:執行完成,提交未能完成。
        終止的:執行過程當中終止,未提交。
        提交的:執行完成,提交完成。
        鎖飢餓:
        死鎖:

        注意:事務一旦提交就沒法撤銷,只能經過補償事務。

    事務調度:
        1.可恢復調度:
        2.無級聯調度:

    保存點(SAVEPOINT):用於在事務中建立保存點,這樣回滾的時候不會所有回滾,只回滾到保存點以前的全部狀態。
        使用SAVEPOINT SPNAME建立保存點。
        使用ROLLBACK TO SPNAME回滾到保存點。



    支持事務要先支持ACID特性
    ACID特性:
        原子性(Automicity):一個事務當中的操做語句要麼都執行完成,要麼都不執行。

        一致性(Consistency):事務完成前和完成後,對數據庫來講狀態是沒有改變的。一致性要在隔離狀態下才能保證。

        隔離性(Isolation):如有2個事務同時執行,其中一個在提交錢前都不被另外一個察覺到。即一個事務的中間過程不影響到其餘操做。服務器使用事務調度(例如MVCC)來使事務間影響最小。

        持久性(Durability):一個事務提交後,即使服務器出現任何故障,也必須保證不引發事務出現不一致性。即事務的操做是持續有效的。
            實現手段:
                1.事務提交前已經將數據寫入硬盤。要消耗大量的磁盤io。
                2.結合事務日誌完成。使用的是順序io而不是向數據文件那樣使用隨機io。速度很是快。


存儲引擎對事務的支持:
    mysql中,是否支持事務,是根據存儲引擎來定義的。
    MyISAM不支持事務。
    InnoDB支持事務。若不明確啓動事務,默認autocommit是啓動的,會自動提交。建議明確使用事務,並關閉自動提交。關閉後若不明確事務,則執行的全部操做都被當作在一個事務中。

事務日誌:
    重作日誌(redo log):
        每次操做都在內存中操做,並寫入重作日誌中記錄。一旦操做完成則表示事務提交。一段時間後,根據日誌內容將操做寫入硬盤。

    撤銷日誌(undo log):
        保留每一次操做前的狀態。以便恢復。

日誌組:
    日誌也是文件,文件中只記錄操做,不記錄對應的數據。
    多個日誌文件構成日誌組。
    日誌文件是輪流使用。一個記錄滿之後自動記錄到下個文件中。記錄滿的日誌文件會將操做同步到硬盤。而後清空日誌。

    日誌文件的大小要根據具體需求定義。

    詳細請參考日誌相關。

事務隔離等級:
    爲了解決多事務交互中出現的各類問題。採用此機制

    級別越高,安全性越好,併發能力越弱。

    READ-UNCOMMITED 讀未提交。最低級別。一個事務執行完成後另外一個事務立刻能看到。此時前一個事務還未能提交。事務之間干擾最大。

    READ-COMMITTED 讀提交。一個事務提交後才能看到。不提交其餘事務看到的不變化。

    REPEATABLE-READ 可重讀。一個事務不管提交與否,另外一個事務在提交前看到的不變化,一旦該事務提交,則看到的是最終值。InnoDB默認級別爲此。


    SERIALIZABLE 可串行。最高級別。能夠同時啓動多個事務,但一個時間內只能執行一個事務。另外一個事務想要操做必須等前面的事務提交完畢後才行。

    mysql默認是REPEATABLE-READ。大多數SQL默認是READ-COMMITTED

    使用SHOW GOBAL VARIABLES LIKE ‘tx_isolation’查看。


分佈式事務(XA):
    是一種高層次的事務,使用兩段式方式(準備-提交 prepare-then-commit)將ACID屬性擴展到存儲引擎的外幣,甚至是數據庫外部。

    準備階段:
        事務協調員同時全部參與者準備提交事務

    提交階段:
        事務協調員在收到全部參與者發出的就緒信息是,會指示全部參與者進行真正的提交操做。

    默認InnoDB是啓用分佈式事務的,使用SHOW GLOBAL VARIABLES LIKE ‘innodb_support_xa’查看



實例:
    1.啓動一個事務:
        mysql>START TRANSACTION;

        啓動後的操做都被認爲是事務中的操做

    2.執行操做:
        mysql> DELETE FROM students WHERE Name LIKE 'stu%';

    3.完成操做後提交:
        mysql>COMMIT;

        注意:一旦提交將不能回滾。

    4.或者是回滾:
        mysql>ROLLBACK;

    5.修改服務器設置,禁用自動提交
        mysql默認是啓動自動提交的,即執行操做後立刻提交,這樣會佔用大量的磁盤io,下降性能。

        mysql> SELECT @@autocommit;
        mysql> SET autocommit=0;

    6.建立保存點:
        使用
        mysql>SAVEPOINT abc;

    7.回滾到某個保存點:
        mysql>ROLLBACK TO abc;

    8.查看當前的隔離級別:
        mysql>SELECT @@tx_isolation;

    9.修改當前會話隔離級別:
        mysql>SET tx_isolation=‘LEVEL’;

    10.修改全局隔離級別:
        #vim /etc/my.cnf
            [mysqld]
            ...
            transaction-isolation = LEVELmysql

相關文章
相關標籤/搜索