亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

sql之事務和并發

系統 1996 0

sql之事務和并發

1、Transaction(事務)是什么:

?事務是作為單一工作單元而執行的一系列操作。包括增刪查改。

2、事務的種類:

?事務分為顯示事務和隱式事務:

隱式事務:就是平常我們使用每一條sql 語句就是一個事務,只不過他們執行完成之后事務就跟著結束了。

顯示事務:就是需要我們來手寫了,這個時候就可以進行控制事務的開始和結束了。

      
         1
      
      
        --
      
      
        顯式事務(對事物可以進行控制)
      
      
         2
      
      
         3
      
      
        --
      
      
        開始事務
      
      
         4
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
         5
      
      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
         6
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        順豐
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        5
      
      
        ;


      
      
         7
      
      
         8
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        ;


      
      
         9
      
      
        10
      
      
        --
      
      
        結束事務:
      
      
        11
      
      
        --
      
      
        第一種:事務的回滾
      
      
        12
      
      
        rollback
      
      
        ;


      
      
        13
      
      
        14
      
      
        --
      
      
        第二種:事務的提交
      
      
        15
      
      
        commit
      
      ;
    

?

3、事務很重要的四個屬性:?

?1、 原子性 :事務必須是原子工作單位?!谑聞罩行薷臄祿?,要么全都執行,要么全都不執行。在事務執行完成之前(調提交指令寫入到sql的事務日志之前),出現問題或重啟,sql server 會回滾所有的修改事務。 但是也有例外的錯誤不會回滾事務————例如:主鍵沖突和鎖超時等。 ?錯誤日志會 捕獲這些錯誤的指令,并記錄日志里面,然后執行一些操作(例如:回滾事務)

?

2、 一致性 :發生在同一進程的事物里面的 修改和 查詢是不會產生沖突的。保持訪問的數據的一致性。

?

3、 隔離性 :控制數據訪問的機制; 說明: 一個事務正在對一個表的數據正在修改, 還沒有執行完成;;這時另一個事務,想要查詢里面的數據,是不能查到的,必須等到 修改的事務執行完成。:sql server 采用的 “鎖”的機制,將正在修改的事務 處理的表的數據 鎖定。這樣是為了保證數據同步,數據的一致性。

?

4、 持久性 : ?當一個事務的指令 已經提交到 事務日志里面,即使磁盤上的數據還沒有修改,這個時候數據庫的服務停止,在服務重啟的時候還會將事務日志里的指令執行(進行回復處理)。保證數據的持久性。

?

上面將基本的事務介紹了一下,下面開始介紹并發。所以必須要介紹就是事務的“鎖”。

4、事務中的鎖

?事務中都含有什么鎖呢?

最常用的鎖:排它鎖(獨占鎖)和共享鎖,還有其他的鎖,這里就不做介紹了,比如:更新鎖、架構鎖、意向鎖等。

?

5、排它鎖和共享鎖

?排它鎖:

當一個事務執行更新修改操作的時候會申請排它鎖,主要是在寫操作里面使用。需要注意的兩點:1、一個事務含有排它鎖,就不能含有其他任何鎖。2、一條數據只能被一個排它鎖鎖住,就不能再被其他排他鎖鎖定。

共享鎖:

?主要是在讀操作中使用,并且多個事務可以同時對一條數據使用共享鎖。

?

排它鎖和共享鎖最重要的區別:排它鎖是不能被控制他的處理方式和時間,但是共享鎖是可以控制其隔離級別來控制其處理的時間。

      
        1
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
        2
      
      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        順豐
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        5
      
      
        ;


      
      
        3
      
      
        --
      
      
        事務還沒有查詢完成,為這條數據 加上一個 排它鎖。這時這條數據就不能被其他進程 訪問到
      
    

?

事務還沒有執行完成,再開一個線程,執行查詢操作

      
        1
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        5
      
    

?

因為讀操作默認使用的共享鎖,但是這個時候這條數據已經被其他線程的排它鎖鎖住,所以會造成阻塞,直到排它鎖釋放。

?

6、隔離級別?

?首先要先明白三點:

1、用于控制并發用戶如何讀寫數據的操做。

2、讀操作默認使用共享鎖;寫操作需要使用排它鎖。

3、讀操作能夠控制他的處理的方式,寫操作不能控制它的處理方式

?

隔離級別分為六種:

read uncommited(讀取未提交數據),read commited(讀取已提交數據)讀取的默認方式,repeatable read(可重復讀),serializable(可序列化),snapshot(快照),read commited snapshot(已經提交讀隔離)(后兩個是sql server 2005 里面 引入的)。隔離的強度依次遞增。

?

?1、read uncommitted:

      
        1
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
    

?

?查詢結果:

在本線程內執行:

      
        1
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
        2
      
      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        圓通
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
    

?

在另外一個線程內 使用 read uncommitted 隔離級別 查詢數據:

      
        1
      
      
        --
      
      
        設置讀操作的隔離級別
      
      
        2
      
      
        set
      
      
        transaction
      
      
        isolation
      
      
        level
      
      
        read
      
      
        uncommitted
      
      
        ;


      
      
        3
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        3;
      
    

?查詢結果:

如果這個時候將那個事務回滾,那么這個時候 ?查詢到的數據就是“臟數據”。

總結:

read uncommitted:最低的隔離級別:查詢的時候不會請求共享鎖,所以不會和排它鎖產生沖突(不會等待排它鎖執行完),查詢效率非常高,速度飛快。但是缺點:會查到“臟數據”(排它鎖的事務已經將數據修改,還沒提交,這個時候查詢到的數據 是已經更改過的。如果事務回滾,就是“臟數據”)

優點:查詢效率非常高,速度非???。

缺點:會產生“臟數據”

適用性:

適用于 像聊天軟件的 聊天記錄,會是軟件的運行速度非常快。 但是不適用于 商務軟件。尤其是銀行

?

2、read committed

?讀取的默認隔離級別就是read committed 和上面正好相反。如果上面情況,采用read committed 隔離級別查詢的話查到的就是還沒有更改之前的數據。

?所以在這里就不再演示。

3、repeatable read:

?查詢的時候會加上共享鎖,但是查詢完成之后,共享鎖就會被撤銷。比如一些購票系統,如果查到票了,當買的時候就沒有,這是不行的。所以要在查詢到數據之后做一些延遲共享鎖,進而阻塞排它鎖來修改。

在查詢線程里面執行sql語句:

      
        1
      
      
        set
      
      
        transaction
      
      
        isolation
      
      
        level
      
      
        repeatable
      
      
        read
      
      
        ;


      
      
        2
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
        3
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        4
      
      ;
    

?

然后在 另外一個線程內執行修改語句:

      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        shit
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        4
      
      ;
    

?

這個時候會將更改的線程阻塞掉:

sql之事務和并發

?

4、serializable(可序列化)

?更高級的 隔離。用戶解決“幻讀”。就是使用上面的 ?加上共享鎖 并不撤銷,如果鎖定的 一行數據,那么 其他的進程 還可以對 其他的數據進行操作,也可以 進行新增和刪除的操作。 ? 所以如果想要在查詢的時候,不能對整張表進行任何操作,那么就要 將表的結構也 鎖定 ? ?(就需要使用 更強的 鎖定)

在查詢線程執行sql語句:

      
        1
      
      
        set
      
      
        transaction
      
      
        isolation
      
      
        level
      
      
        serializable
      
      
        ;


      
      
        2
      
      
        3
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
        4
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
    

?

那么在另外一個線程執行下面兩個語句,不論那一條語句都會阻塞?。?

      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        聯邦
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      
        ;




      
      
        insert
      
      
        into
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
       (companyname,phone) 
      
        values
      
      (
      
        '
      
      
        韻達
      
      
        '
      
      ,
      
        '
      
      
        12345678
      
      
        '
      
      )
    

?

總結:

可序列話 隔離讀操作:用戶 解決 幻影數據(將標的數據和表的結構都鎖定),是并發降低...隔離級別越高,并發越低,但是效率越低,所以不是要確定使用 ?最好不要使用

?

下面兩種隔離級別是在 sql server 2005才出現的,隔離級別更高:

5、snapshot(快照)

?為數據產生一個臨時數據庫,當sql server 數據更新之前將當前數據庫復制到 tempdb數據庫里面,查詢就是從tempdb數據庫中查詢

      
        --
      
      
        設置數據庫支持快照隔離級別:
      
      
        alter
      
      
        database
      
       ssdemo 
      
        set
      
       allow_snapshot_isolation 
      
        on
      
      ;
      
        --
      
      
        這個時候會產生一個臨時數據庫(寫操作的排它鎖鎖定的是 現實存在的數據庫,,讀操作的讀取的是 臨時數據庫)
      
    

?

?在一個線程中執行 更新操作,用排它鎖鎖定當前數據

      
        begin
      
      
        transaction
      
      
        ;


      
      
        --
      
      
        使用 排它鎖(獨占鎖)X,鎖定 下面的那條數據
      
      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        飛鳳
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
    

?

這個時候在在另外一個線程中查詢這條數據(默認的隔離級別),就會將當前線程阻塞。

如果使用 snapshot 隔離級別查詢就不會阻塞。

      
        1
      
      
        set
      
      
        transaction
      
      
        isolation
      
      
        level
      
      
         snapshot;


      
      
        2
      
      
        --
      
      
        下面的就可以  從臨時數據庫中查詢到數據
      
      
        3
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
        4
      
      
        --
      
      
        使用 共享鎖 S
      
      
        5
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
      
        --
      
      
        查詢到的 是還沒有完成更新之前的數據
      
    

?

但是同時也會帶來兩個問題:

1、當 另外一個事務 ?已經提交,但是這邊的查詢到數據還是沒有修改。因為 每次查詢到的快照是針對于 本次回話對應的那個 transaction 的,因為在這個事務里面是沒有修改的,所以查詢到的數據是沒有修改的。

2、(更新問題)因為 那邊的數據已經是 飛鳳公司了,但是這里還是 ? 聯邦,所以,在這個事務里面是不能對表進行修改,因為訪問的是臨時數據庫,想要對 數據庫修改是不可能的(sql server 就會報錯,阻止修改)?

?

針對于上面兩個問題,所以下面 更高的隔離級別出現了 read committed snapshot:

6、read committed snapshot

?首先開啟數據庫的 read committed snapshot 隔離級別:

      
        1
      
      
        --
      
      
        設置 數據庫 為 讀取已經提交的快照 開啟
      
      
        2
      
      
        alter
      
      
        database
      
       ssdemo 
      
        set
      
       read_committed_snapshot 
      
        on
      
      ;
    

?

在一個線程中執行:

      
        begin
      
      
        transaction
      
      
        ;


      
      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        聯邦
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
    

?

在另外一個線程中:

      
        1
      
      
        --
      
      
        不用顯示聲明使用  read committed snapshot 隔離級別,因為設置完 read_committed_snapshot 隔離級別啟動,默認就是 read commited snapshot 隔離級別
      
      
        2
      
      
        begin
      
      
        transaction
      
      
        ;


      
      
        3
      
      
        select
      
      
        *
      
      
        from
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
      
        --
      
      
        查詢到是 已經提交之后的數據
      
      
        4
      
      
        5
      
      
        update
      
      
        [
      
      
        Sales.Shippers
      
      
        ]
      
      
        set
      
       companyname
      
        =
      
      
        '
      
      
        xiaoxiao
      
      
        '
      
      
        where
      
       shipperid
      
        =
      
      
        3
      
      ;
    

?

這個時候查詢到的數據是還沒有更改之前的,如果將 前面的那個回話提交,那么在查詢 查詢到的數據是 提交修改之后的數據。所以解決了上面的問題1.

如果在修改的話。也是在第一個 更新線程中的事務更新之后的數據進行執行修改的操作,不會報錯。

?

?

?

?

?
?
分類:? sql

sql之事務和并發


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!??!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 99九九精品视频 | 久久国产乱子伦精品免费一 | 女女同免费播放毛片 | 国产永久一区二区三区 | 五月情婷婷 | 中文字幕中文字幕中中文 | 天天狠狠弄夜夜狠狠躁·太爽了 | 免费黄色一级大片 | 国产玖玖在线 | 狠狠r| 日本人一级大毛片 | 亚洲欧美一区二区三区在线播放 | 激情综合五月 | 国产成人精品免费视频网页大全 | 亚洲乱码中文字幕综合 | 美女胸又大又黄www网站 | 欧美日韩成人午夜免费 | avtt亚洲一区中文字幕 | 在线免费观看亚洲 | 5060网午夜一级毛片在线看 | 日本a在线| 又粗又大的机巴好爽欧美 | 全黄一级裸片视频免费区 | 高清影院|精品秒播3 | 日韩伊人 | 欧美成人久久久免费播放 | 久久久久久噜噜噜久久久精品 | 四虎影院在线视频 | 免费一级a毛片在线 | 97在线视频免费公开观看 | 在线免费一区二区 | 免费人成激情视频在线观看冫 | 四虎免费在线 | 日韩精品一区二区三区中文在线 | 欧美日本高清动作片www网站 | 国产一级毛片大陆 | 亚洲一区二区三区在线视频 | 日日网站 | 久久香蕉国产线看观看乱码 | 狠狠色丁香婷婷综合最新地址 | 激情婷婷在线 |