1. 程式人生 > >db事務級別及鎖

db事務級別及鎖

ransac databases snap 對象 類型 t_sql 數據挖掘 不兼容 sna

相關sql

事務A

BEGIN TRANSACTION

    --執行修改 獲取排他鎖
    UPDATE Product
    SET Price = 10
    WHERE Id = 1

    --階段2
    UPDATE Product
    SET Price = Price + 1
    WHERE Id = 1 

    SELECT * FROM Product
    WHERE Id = 1 

    --階段3
    UPDATE Product
    SET Price = Price + 5
    WHERE Id = 1 

    SELECT * FROM Product
    WHERE Id = 1 

--階段4
COMMIT TRANSACTION

事務B

--2.隔離級別的分類
--(1)未提交讀 (READ UNCOMMITTED)

--(2)已提交讀(READ COMMITTED)(默認值)

--(3)可重復讀(REPEATABLE READ)

--(4)可序列化(SERIALIZABLE)

--(5)快照(SNAPSHOT)

--(6)已經提交讀快照(READ_COMMITTED_SNAPSHOT)

--BEGIN TRANSACTION

--  --未提交讀
--  SET TRAN ISOLATION LEVEL READ UNCOMMITTED

--  SELECT * FROM Product--與事務A各階段顯示相同
--  WHERE Id = 1 

--(1)讀操作可以讀取未提交的修改(也稱為臟讀)。

--(2)讀操作不會妨礙寫操作請求排他鎖,其他事務正在進行讀操作時,寫操作可以同時對這些數據進行修改。

--(3)事務A進行了多次修改,事務B在不同階段進行查詢時可能會有不同的結果。
--COMMIT TRANSACTION



--BEGIN TRANSACTION

--  --已提交讀【默認級別】
--  SET TRAN ISOLATION LEVEL READ COMMITTED

--  --讀取獲取共享鎖  
--  --當查詢信息具有排他鎖 需等待至排他鎖結束
--  SELECT * FROM Product--與事務A各階段顯示相同
--  WHERE Id = 1 

----(1)必須獲得共享鎖才能進行讀操作,其他事務如果對該資源持有排他鎖,則共享鎖必須等待排他鎖釋放。

----(2)讀操作不能讀取未提交的修改,讀操作讀取到的數據是提交過的修改。

----(3)讀操作不會在事務持續期間內保留共享鎖,其他事務可以在兩個讀操作之間更改數據資源,讀操作因而可能每次得到不同的取值。這種現象稱為“不可重復讀”
    
--COMMIT TRANSACTION

--★ 3.可重復讀(REPEATABLE READ)
--BEGIN TRANSACTION

--  SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
--  SELECT * FROM Product WHERE Id = 1

--(1)必須獲得共享鎖才能進行讀操作,獲得的共享鎖將一直保持直到事務完成之止。

--(2)在獲得共享鎖的事務完成之前,沒有其他事務能夠獲得排他鎖修改這一數據資源,這樣可以保證實現可重復的讀取。

--(3)兩個事務在第一次讀操作之後都將保留它們獲得的共享鎖,所以任何一個事務都不能獲得為了更新數據而需要的排他鎖,這種情況將會導致死鎖(deadlock),不過卻避免了更新沖突。

--COMMIT TRANSACTION

--★ 4.可序列化(SERIALIZABLE)
BEGIN TRANSACTION

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    SELECT * FROM Product WHERE Id = 1

--“可序列化(SERIALIZABLE)”隔離級別的含義:

--(1)必須獲得共享鎖才能進行讀操作,獲得的共享鎖將一直保持直到事務完成之止。

--(2)在獲得共享鎖的事務完成之前,沒有其他事務能夠獲得排他鎖修改這一數據資源,且當其他事務增加能夠滿足當前事務的讀操作的查詢搜索條件的新行時,其他事務將會被阻塞,直到當前事務完成然後釋放共享鎖,其他事務才能獲得排他鎖進行插入操作。

--(3)事務中的讀操作在任何情況下讀取到的數據是一致的,不會出現幻影行(幻讀)。

--(4)範圍鎖:讀操作鎖定滿足查詢搜索條件範圍的鎖

COMMIT TRANSACTION

相關信息

--2.隔離級別的分類
--(1)未提交讀 (READ UNCOMMITTED)

--(2)已提交讀(READ COMMITTED)(默認值)

--(3)可重復讀(REPEATABLE READ)

--(4)可序列化(SERIALIZABLE)

--(5)快照(SNAPSHOT)

--(6)已經提交讀快照(READ_COMMITTED_SNAPSHOT)


--5.sys.dm_exec_requests 視圖
--識別出阻塞鏈涉及到的會話、爭用的資源、被阻塞會話等待了多長時間
--SELECT session_id FROM sys.dm_exec_sessions

--★ 1.sys.dm_tran_locks 視圖

--(1)該動態視圖可以查詢出哪些資源被哪個進程ID鎖了

--(2)查詢出對資源授予或正在等待的鎖模式

--(3)查詢出被鎖定資源的類型

--上面的查詢語句3已經用到了這個視圖,可以參考上圖中的分析說明。

SELECT request_session_id AS 會話id ,
resource_type AS 請求鎖定的資源類型 ,
resource_description AS 描述 ,
request_mode AS 模式 ,
request_status AS 狀態
FROM sys.dm_tran_locks

--2.sys.dm_exec_connections 視圖

--(1)查詢出該動態視圖可以查詢出進程相關的信息

--(2)查詢出最後一次發生讀操作和寫操作的時間last_read,last_write

--(3)查詢出進程執行的最後一個SQL批處理的二進制標記most_recent_sql_handle

--SELECT  session_id ,
--        connect_time ,
--        last_read ,
--        last_write ,
--        most_recent_sql_handle
--FROM    sys.dm_exec_connections
 

-- dm_exec_sql_text

--(1)該函數可以將二進制標記most_recent_sql_handle作為參數,然後返回SQL代碼。

--(2)阻塞進程在不斷地運行,所以在代碼中看到的最後一個操作不一定是導致問題的語句。在本例中最後一條執行語句是導致阻塞的語句。 

--SELECT  session_id ,
--        text
--FROM    sys.dm_exec_connections
--        CROSS APPLY sys.dm_exec_sql_text
--        (most_recent_sql_handle) AS ST

--結束會話
--KILL 52

--5.隔離級別總結

--臟讀:讀取未提交的更改。

--不可重復讀:讀操作不會在事務持續期間內保留共享鎖,其他事務可以在兩個讀操作之間更改數據資源,讀操作因而可能每次得到不同的取值。

--丟失更新:兩個事務進行讀操作,獲得資源上的共享鎖,讀取完數據後,不再持有資源上的任何鎖,兩個事務都能更新這個值,

--    最後進行更新的事務將會覆蓋其他事務做的更改,導致其他事務更改的數據丟失。

--幻讀:第一次和第二次讀取到的數據行數不一致。

--範圍鎖:讀操作鎖定滿足查詢搜索條件範圍的鎖

--“死鎖 (Dead Lock)”的一些註意事項:

--(1)如果兩個事務沒有設置死鎖優先級,且兩個事務進行的工作量也差不多一樣時,任何一個事務都有可能被終止。

--(2)解除死鎖要付出一定的系統開銷,因為這個過程會涉及撤銷已經執行過的處理。

--(3)事務處理的時間時間越長,持有鎖的時間就越長,死鎖的可能性也就越大,應該盡可能保持事務簡短,把邏輯上可以不屬於同一個工作單元的操作移到事務以外。

--(4)上面的例子中,事務A和事務B以相反順序訪問資源,所以發生了死鎖。如果兩個事務按同樣的順序來訪問資源,則不會發生這種類型的死鎖。在不改變程序的邏輯情況下,可以通過交換順序來解決死鎖的問題。

臟數據

<wiki>從廣義上看,臟數據是指沒有進行過數據預處理而直接接收到的、處於原始狀態的數據;
從狹義上看,是不符合研究要求,以及不能夠對其直接進行相應的數據分析。
臟數據依據不同的分析目的有不同的定義,
如在常見的數據挖掘工作中,臟數據是指不完整、含噪聲、不一致的數據;
而在問卷分析中,臟數據則是指不符合問卷要求的數據。

<bky>臟讀dirty reads:當事務讀取還未被提交的數據時,就會發生這種事件。舉例來說:  

    事務a  修改了一行數據,然後   
    事務b  在   
    事務a  還未提交修改操作之前讀取了被修改的行。如果   
    事務a  回滾了修改操作,那麽   
    事務b  讀取的數據就可以看作是從未存在過的。 ?

即 臟數據為還未進行保存的數據,即數據庫中不存在的數據

lock 鎖

1.事務中的鎖

(1)SQL Server使用鎖來實現事務的隔離。

(2)事務獲取鎖這種控制資源,用於保護數據資源,防止其他事務對數據進行沖突的或不兼容的訪問。

(3) 通過鎖來確保在此次事務完成之前不會有其他事務會更改此事務需要操作的數據

2.鎖模式

(1)排他鎖

  a.當試圖修改數據時,事務只能為所依賴的數據資源請求排他鎖。

  b.持有排他鎖時間:一旦某個事務得到了排他鎖,則這個事務將一直持有排他鎖直到事務完成。

  c.排他鎖和其他任何類型的鎖在多事務中不能在同一階段作用於同一個資源。

    如:當前事務獲得了某個資源的排他鎖,則其他事務不能獲得該資源的任何其他類型的鎖。其他事務獲得了某個資源的任何其他類型的鎖,則當前事務不能獲得該資源的排他鎖。

(2)共享鎖

  a.當試圖讀取數據時,事務默認會為所依賴的數據資源請求共享鎖。

  b.持有共享鎖時間:從事務得到共享鎖到讀操作完成。

  c.多個事務可以在同一階段用共享鎖作用於同一數據資源。

  d.在讀取數據時,可以對如何處理鎖定進行控制。後面隔離級別會講到如何對鎖定進行控制。

3.排他鎖和共享鎖的兼容性

(1)如果數據正在由一個事務進行修改,則其他事務既不能修改該數據,也不能讀取(至少默認不能)該數據,直到第一個事務完成。

(2)如果數據正在由一個事務讀取,則其他事務不能修改該數據(至少默認不能)。

4.可鎖定的資源的類型

RID、KEY(行)、PAGE(頁)、對象(例如表)、數據庫、EXTENT(區)、分配單元(ALLOCATION_UNIT)、堆(HEAP)、以及B樹(B-tree)。
RID: 標識頁上的特定行
  格式: fileid: pagenumber: rid (1:109:0 )
    其中fileid標識包含頁的文件, pagenumber標識包含行的頁,rid標識頁上的特定行。
    fileid與sys.databases_files 目錄視圖中的file_id列相匹配
  例子:
    在查詢視圖sys.dm_tran_locks的時候有一行的resource_description列顯示RID 是1:109:0 而status列顯示wait,
    表示第1個數據文件上的第109頁上的第0行上的鎖資源。

summary

IsoLevel 是否讀取未提交的行 是否不可重復讀 是否丟失更新 是否幻讀 共享鎖持續時間 是否持有範圍鎖
未提交讀 Y Y Y Y 當前語句 N
已提交讀 N Y Y Y 當前語句 N
可重復讀 N N N Y 整個事務 N
可序列化 N N N N 整個事務 Y

可重復讀不會出現丟失更新。。。


https://www.cnblogs.com/jackson0714/p/TSQLFundamentals_08.html


author:monster

direction:lock

date:1/24/2019 3:12:07 PM

db事務級別及鎖