Gay Bird

          登高者必自卑,行遠者必自邇,在這個世界上,重要的不是你正站在那里,而是你正朝什么方向移動......

          MSSQL事務(wù)、事務(wù)隔離級別、鎖的簡單總結(jié)

          一、數(shù)據(jù)庫事務(wù)
          1、事務(wù)是作為單個邏輯工作單元執(zhí)行的一系列操作。可以是一條SQL語句也可以是多條SQL語句。

          2、事務(wù)具有四個特性
             原子性:不可分隔、成則具成、敗則具敗。
             恢灤裕菏攣裨諭瓿墑保 匭朧顧 械氖 荻急3忠恢倫刺?
             隔離性:獨立的執(zhí)行互不干擾。由并發(fā)事務(wù)所作的修改必須與任何其他并發(fā)事務(wù)所作的修改隔離(另外的描述:多個事務(wù)同時進行,它們之間應(yīng)該互不干擾.應(yīng)該防止一個事務(wù)處理其他事務(wù)也要修改的數(shù)據(jù)時,不合理的存取和不完整的讀取數(shù)據(jù))
            
          3、啟動事務(wù):使用 API 函數(shù)和 Transact-SQL 語句,可以按顯式、自動提交或隱式的方式來啟動事務(wù)。

          4、結(jié)束事務(wù):您可以使用 COMMIT(成功) 或 ROLLBACK(失敗) 語句,或者通過 API 函數(shù)來結(jié)束事務(wù)。

          5、創(chuàng)建事務(wù)的原則:
             盡可能使事務(wù)保持簡短很重要,當事務(wù)啟動后,數(shù)據(jù)庫管理系統(tǒng) (DBMS) 必須在事務(wù)結(jié)束之前保留很多資源、以保證事務(wù)的正確安全執(zhí)行。
             特別是在大量并發(fā)的系統(tǒng)中, 保持事務(wù)簡短以減少并發(fā) 資源鎖定爭奪,將先得更為重要。
             1、事務(wù)處理,禁止與用戶交互,在事務(wù)開始前完成用戶輸入。
             2、在瀏覽數(shù)據(jù)時,盡量不要打開事務(wù)
             3、盡可能使事務(wù)保持簡短。
             4、考慮為只讀查詢使用快照隔離,以減少阻塞。
             5、靈活地使用更低的事務(wù)隔離級別。
             6、靈活地使用更低的游標并發(fā)選項,例如開放式并發(fā)選項。
             7、在事務(wù)中盡量使訪問的數(shù)據(jù)量最小。

           

          二、事務(wù)的隔離級別

          1、數(shù)據(jù)庫事務(wù)的隔離級別:四種

          隔離級別 臟讀(Dirty Read) 不可重復(fù)讀(NonRepeatable Read) 幻讀(Phantom Read)
          讀未提交(Read uncommitted) 可能 可能 可能
          讀已提交(Read committed) 不可能 可能 可能
          可重復(fù)讀(Repeatable read) 不可能 不可能 可能
          可串行化(Serializable ) 不可能 不可能 不可能

          2、數(shù)據(jù)庫一般的默認隔離離級別是“讀已提交”,默認的事務(wù)隔離級別下:Insert,update ,delete下的是X鎖, 會等待事務(wù)完成。通常情況下可以把隔離級別設(shè)為Read Commited,它能避免臟讀,而且有較好的并發(fā)性能。盡管它會導(dǎo)致不可重復(fù)讀、虛讀和第二類更新丟失等問題,在可能出現(xiàn)這類問題的個別場合可以由應(yīng)用程序釆用悲觀鎖或樂觀鎖來控制。


          3、SQL語句可以使用SET TRANSACTION ISOLATION LEVEL來設(shè)置事務(wù)的隔離級別。如:SET TRANSACTION ISOLATION LEVEL   Read Committed。若要在應(yīng)用程序中使用更嚴格或較寬松的隔離級別,可以通過使用   set transaction isolation level語句設(shè)置會話的隔離級別,來自定義整個會話的鎖定。  
          指定隔離級別后,sql server會話中所有select語句的鎖定行為都運行于該隔離級別上,并一直保持有效直到會話終止或者將隔離級別設(shè)置為另一個級別。

          4、另外要提一點:SQL標準對事務(wù)隔離級別的規(guī)定,是按該級別不可能發(fā)生什么問題來確定的,不一定會發(fā)生這樣的問題;所以,不同的數(shù)據(jù)庫對事務(wù)隔離的級別約定不一樣,比如,有的數(shù)據(jù)庫把 可重復(fù)讀級別按可串行化來對待。(lkdlhw_2000個人理解:各個數(shù)據(jù)庫應(yīng)該都遵循四種標準的事務(wù)隔離等級的定義,但是某些數(shù)據(jù)庫具體實現(xiàn)可能不存在四種,因為串行化可以避免不可重復(fù)讀,因此某些數(shù)據(jù)庫語法上支持設(shè)置事務(wù)隔離等級為不可重復(fù)讀,但實際上是串行化在起作用。也就是說只要該級別能夠避免不可重復(fù)讀的問題,就可以稱之為不可重復(fù)讀取級別。)

          5、該隔離級別定義一個事務(wù)必須與其他事務(wù)所進行的資源或數(shù)據(jù)更改相隔離的程度。事務(wù)隔離級別控制:
               讀取數(shù)據(jù)時是否占用鎖以及所請求的鎖類型。
               占用讀取鎖的時間。
               引用其他事務(wù)修改的行的讀取操作是否:
               在該行上的排他鎖被釋放之前阻塞其他事務(wù)。
               檢索在啟動語句或事務(wù)時存在的行的已提交版本。
               讀取未提交的數(shù)據(jù)修改

          三、鎖

          1、分類:從數(shù)據(jù)庫系統(tǒng)的角度來看:分為獨占鎖(即排它鎖),共享鎖和更新鎖

          2、事務(wù)使用鎖,防止其他用戶修改另外一個還沒有完成的事務(wù)中的數(shù)據(jù)。對于多用戶系統(tǒng)來說,鎖機制是必須的。SQL Server有多種鎖,允許事務(wù)鎖定不同的資源。鎖就是保護指定的資源,不被其他事務(wù)操作。SQL Server有多種鎖,允許事務(wù)鎖定不同的資源。鎖就是保護指定的資源,不被其他事務(wù)操作。為了最小化鎖的成本,SQL Server自動地以與任務(wù)相應(yīng)等級的鎖來鎖定資源對象。鎖定比較小的對象,例如鎖定行,雖然可以提高并發(fā)性,但是卻有較高的開支,因為如果鎖定許多行,那么需要占有更多的鎖。鎖定比較大的對象,例如鎖定表,會大大降低并發(fā)性,因為鎖定整個表就限制了其他事務(wù)訪問該表的其他部分,但是成本開支比較低,因為只需維護比較少的鎖。

          3、 鎖的特點:
          1. 鎖是保證并發(fā)控制的手段
          2. 可以鎖定的資源包括行、頁、簇、表和數(shù)據(jù)庫
          3. 鎖的類型主要包括共享鎖和排它鎖
          4. 特殊類型的鎖包括意圖鎖、修改鎖和模式鎖
          5. 共享鎖允許其他事務(wù)繼續(xù)使用鎖定的資源
          6. 排它鎖只允許一個事務(wù)訪問數(shù)據(jù)
          7. 系統(tǒng)本身可以處理死鎖
          8. 用戶可以根據(jù)實際情況定制鎖的一些特征

          4、鎖是定義到sql語句上的,對數(shù)據(jù)進行操作的sql就是:select,Insert,update ,delete。不同的事物隔離即被在執(zhí)行sql的時候會向表上發(fā)送不同的鎖。

          關(guān)于鎖的更多描述,可以去網(wǎng)上搜索一下。http://www.bitscn.com/windows/sql/200604/1068.html

          四、多個用戶同時對數(shù)據(jù)庫的并發(fā)操作時會帶來以下數(shù)據(jù)不一致的問題:

          臟讀dirty reads:
             當事務(wù)讀取還未被提交的數(shù)據(jù)時,就會發(fā)生這種事件。舉例來說:Transaction1修改了一行數(shù)據(jù),然后Transaction2在Transaction1還未提交修改操作之前讀取了被修改的行。如果Transaction1回滾了修改操作,那么Transaction2讀取的數(shù)據(jù)就可以看作是從未存在過的。
          不可重復(fù)的讀non-repeatable reads:
             當事務(wù)兩次讀取同一行數(shù)據(jù),但每次得到的數(shù)據(jù)都不一樣時,就會發(fā)生這種事件。舉例來說:Transaction1讀取一行數(shù)據(jù),然后Transaction2修改或刪除該行并提交修改操作。當Transaction1試圖重新讀取該行時,它就會得到不同的數(shù)據(jù)值(如果該行被更新)或發(fā)現(xiàn)該行不再存在(如果該行被刪除)。    
          虛讀phantom read:
             如果符合搜索條件的一行數(shù)據(jù)在后面的讀取操作中出現(xiàn),但該行數(shù)據(jù)卻不屬于最初的數(shù)據(jù),就會發(fā)生這種事件。舉例來說Transactio1讀取滿足某種搜索條件的一些行,然后Transaction2插入了符合Transaction1的搜索條件的一個新行。如果Transaction1重新執(zhí)行產(chǎn)生原來那些行的查詢,就會得到不同的行。

          為了解決這些問題,數(shù)據(jù)庫引入了“鎖”的機制(從數(shù)據(jù)庫系統(tǒng)的角度來看:分為獨占鎖(即排它鎖),共享鎖和更新鎖,詳細內(nèi)容不再描述)。

           

          五、lkdlhw_2000個人理解(以下問題都是推測,還沒有證實):

          隔離級別是由鎖來實現(xiàn)的,之所以出現(xiàn)事務(wù)的隔離級別相當于數(shù)據(jù)庫開發(fā)商根據(jù)一般的業(yè)務(wù)需求實現(xiàn)定義好的一組鎖使用的規(guī)則,便于我們時候,當我們將事務(wù)隔離級別定義到某一級上后如果不能滿足需求,我們還可以自行定義sql的鎖來覆蓋事務(wù)隔離級別默認的鎖機制?

          鎖存在兩個問題:一個是鎖的粒度,一個是鎖的時間,鎖的時間應(yīng)該包括兩種一種是sql執(zhí)行完就釋放鎖,領(lǐng)一中是事務(wù)結(jié)束后釋放鎖

          六、參考文章

          http://www.es-ivision.com/Channel-4-10-108-0.html
          http://tech.ccidnet.com/art/1105/20050602/261573_1.html
          http://www.aygfsteel.com/zhengtengfeng/archive/2007/04/23/113025.html

          七、事務(wù)隔離級別的例子

          1. Read Uncommitted:最低等級的事務(wù)隔離,僅僅保證了讀取過程中不會讀取到非法數(shù)據(jù)。上訴4種不確定情況均有可能發(fā)生。
          2. Read Committed:大多數(shù)主流數(shù)據(jù)庫的默認事務(wù)等級,保證了一個事務(wù)不會讀到另一個并行事務(wù)已修改但未提交的數(shù)據(jù),避免了“臟讀取”。該級別適用于大多數(shù)系統(tǒng)。
          第一個查詢事務(wù)
          SET TRANSACTION ISOLATION LEVEL   Read Committed
          begin tran
             update Cate SET Sname=Sname+'b' where ID=1
             SELECT * FROM cate where ID=1
             waitfor delay '00:00:6'  
             rollback tran --回滾事務(wù)
          select Getdate()
          SELECT * FROM cate where ID=1
          第二個查詢事務(wù)
          SET TRANSACTION ISOLATION LEVEL Read committed   --把committed換成Read uncommitted可看到“臟讀取”的示例。
          SELECT * FROM cate where ID=1
          select Getdate()
          可以看到使用 Read Committed 成功的避免了“臟讀取”.
          3. Repeatable Read:保證了一個事務(wù)不會修改已經(jīng)由另一個事務(wù)讀取但未提交(回滾)的數(shù)據(jù)。避免了“臟讀取”和“不可重復(fù)讀取”的情況,但是帶來了更多的性能損失。
          第一個查詢事務(wù)
          SET TRANSACTION ISOLATION LEVEL Repeatable Read --   把Repeatable Read換成Read committed可以看到“不可重復(fù)讀取”的示例
          begin tran
          SELECT * FROM cate where ID=33 --第一次讀取數(shù)據(jù)
             waitfor delay '00:00:6'  
          SELECT * FROM cate where ID=33 --第二次讀取數(shù)據(jù),不可重復(fù)讀取
          commit
          第二個查詢事務(wù)
          SET TRANSACTION ISOLATION LEVEL Read committed
          update cate set Sname=Sname+'JD' where ID=33
          SELECT * FROM cate where ID>30
          4. Serializable:最高等級的事務(wù)隔離,上面3種不確定情況都將被規(guī)避。這個級別將模擬事務(wù)的串行執(zhí)行。
          在第一個查詢窗口執(zhí)行
          SET TRANSACTION ISOLATION LEVEL Serializable -- 把Serializable換成Repeatable Read 可看到“幻像讀”的示例
          begin tran
          SELECT * FROM cate where ID>30 --第一次讀取數(shù)據(jù),“幻像讀”的示例
             waitfor delay '00:00:6'   --延遲6秒讀取
          SELECT * FROM cate where ID>30 --第一次讀取數(shù)據(jù)
          commit
          第二個查詢事務(wù)
          SET TRANSACTION ISOLATION LEVEL Read committed
          Delete from cate where ID>33
          SELECT * FROM cate where ID>30
          創(chuàng)建事務(wù)

          設(shè)置事務(wù)級別:SET TRANSACTION ISOLATION LEVEL
          開始事務(wù):begin tran
          提交事務(wù):COMMIT
          回滾事務(wù):ROLLBACK
          創(chuàng)建事務(wù)保存點:SAVE TRANSACTION savepoint_name
          回滾到事務(wù)點:ROLLBACK TRANSACTION savepoint_name



          1、并發(fā)的影響:http://technet.microsoft.com/zh-cn/library/ms190805.aspx
                該文章列出了并發(fā)引起的四種影響:丟失更新、臟讀(未提交的依賴關(guān)系)、不可重復(fù)讀(不一致的分析)、幻讀
            
          2、并發(fā)控制類型:http://technet.microsoft.com/zh-cn/library/ms189132.aspx
               當許多人試圖同時修改數(shù)據(jù)庫中的數(shù)據(jù)時,必須實現(xiàn)一個控制系統(tǒng),使一個人所做的修改不會對他人所做的修改產(chǎn)生負面影響。這稱為并發(fā)控制。并發(fā)控制類型分為兩大類:樂觀并發(fā)控制和悲觀并發(fā)控制
            
          3、數(shù)據(jù)庫引擎中的隔離級別:http://technet.microsoft.com/zh-cn/library/ms189122.aspx
               1)講到了事務(wù)隔離級別控制的內(nèi)容:
                     事務(wù)隔離級別控制:
                    讀取數(shù)據(jù)時是否占用鎖以及所請求的鎖類型。
                    占用讀取鎖的時間。
                    引用其他事務(wù)修改的行的讀取操作是否:
                           在該行上的排他鎖被釋放之前阻塞其他事務(wù)。
                          檢索在啟動語句或事務(wù)時存在的行的已提交版本。
                           讀取未提交的數(shù)據(jù)修改。
                2)列出了事務(wù)的隔離級別:
                  未提交讀(隔離事務(wù)的最低級別,只能保證不讀取物理上損壞的數(shù)據(jù))
                   已提交讀(數(shù)據(jù)庫引擎的默認級別)
                   可重復(fù)讀
                   可序列化(隔離事務(wù)的最高級別,事務(wù)之間完全隔離)

               3)選擇事務(wù)隔離級別不影響為保護數(shù)據(jù)修改而獲取的鎖。事務(wù)總是在其修改的任何數(shù)據(jù)上獲取排他鎖并在事務(wù)完成之前持有該鎖,不管為該事務(wù)設(shè)置了什么樣的隔離級別。對于讀取操作,事務(wù)隔離級別主要定義保護級別,以防受到其他事務(wù)所做更改的影響。
            
          4、SET TRANSACTION ISOLATION LEVEL (Transact-SQL) 設(shè)置事務(wù)隔離級別http://technet.microsoft.com/zh-cn/library/ms173763.aspx
               該選項的作用與在事務(wù)內(nèi)所有 SELECT 語句中的所有表上設(shè)置 HOLDLOCK 相同
          5、總結(jié):
               通過以上幾篇文章基本上可以了解數(shù)據(jù)庫事務(wù)和鎖之間的關(guān)系。數(shù)據(jù)庫事務(wù)隔級別也是由鎖機制來最實現(xiàn)的。要想了解關(guān)于鎖的更深層析的內(nèi)容還需要專門學習鎖的相關(guān)知識。

          posted on 2008-10-11 13:11 Sky Yi 閱讀(5561) 評論(1)  編輯  收藏

          Feedback

          # re: MSSQL事務(wù)、事務(wù)隔離級別、鎖的簡單總結(jié) 2008-12-29 09:27 iask

          “2、事務(wù)具有四個特性”里面有亂碼  回復(fù)  更多評論   



          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 房产| 牙克石市| 北流市| 从化市| 阜阳市| 吉安县| 石泉县| 黄浦区| 天全县| 孝义市| 福安市| 奉节县| 武山县| 石城县| 远安县| 岑溪市| 三穗县| 崇文区| 漾濞| 古田县| 葫芦岛市| 通化县| 台中市| 儋州市| 云南省| 抚州市| 灯塔市| 温宿县| 玛曲县| 宜昌市| 河北区| 垫江县| 镇江市| 潮州市| 吉木萨尔县| 分宜县| 乐昌市| 武宣县| 历史| 陈巴尔虎旗| 同心县|