SQL Server中的事物

来源:http://www.cnblogs.com/LoveSuk/archive/2016/07/29/5717864.html
-Advertisement-
Play Games

1.事務的四個屬性 原子性Atomicity,一致性Consistency,隔離性Isolation,持久性Durability ,即ACID特性。 原子性:事務必須是一個完整工作的單元,要麼全部執行,要麼全部不執行。 一致性:事務結束的時候,所有的內部數據都是正確的。 隔離性:併發多個事務時,各個 ...


1.事務的四個屬性

原子性Atomicity,一致性Consistency,隔離性Isolation,持久性Durability ,即ACID特性。

原子性:事務必須是一個完整工作的單元,要麼全部執行,要麼全部不執行。

一致性:事務結束的時候,所有的內部數據都是正確的。

隔離性:併發多個事務時,各個事務不幹涉內部數據,處理的都是另外一個事務處理之前或之後的數據。

持久性:事務提交之後,數據是永久性的,不可再回滾。

2.在SQL Server中事務被分為3類常見的事務

自動提交事務:是SQL Server預設的一種事務模式,每條Sql語句都被看成一個事務進行處理。如果成功執行,則自動提交,如果錯誤,則自動回滾。

顯式事務:T-sql標明,由Begin Transaction開啟事務開始,由Commit Transaction 提交事務、Rollback Transaction 回滾事務結束。

隱式事務:使用Set IMPLICIT_TRANSACTIONS ON 將將隱式事務模式打開,不用Begin Transaction開啟事務。當一個事務結束,這個模式會自動啟用下一個事務,只用Commit Transaction 提交事務、Rollback Transaction 回滾事務即可。

3.事物的語法

Begin Transaction:標記事務開始。

Commit Transaction:事務已經成功執行,數據已經處理妥當。

Rollback Transaction:數據處理過程中出錯,回滾到沒有處理之前的數據狀態,或回滾到事務內部的保存點。

Save Transaction:事務內部設置的保存點,就是事務可以不全部回滾,只回滾到這裡,保證事務內部不出錯的前提下。

4.示例

---開啟事務

begin tran

begin try  --在這裡我們可以添加錯誤的撲捉機制

   insert into A(id,name,typeid) values (1,'小王',1)     --語句正確

  -- save tran pigOneIn  --在這裡我們可以添加保存點,保存之前正確的數據

   insert into A(id,name,typeid) values (2,'小李','學生')    --語句類型錯誤

   insert into A(id,name,typeid) values (1,'小張',2)     --語句正確

end try

begin catch

   SELECT Error_number() as ErrorNumber,  --錯誤代碼

        Error_severity() as ErrorSeverity,  --錯誤嚴重級別,級別小於10 try catch 捕獲不到

        Error_state() as ErrorState ,  --錯誤狀態碼

        Error_Procedure() as ErrorProcedure , --出現錯誤的存儲過程或觸發器的名稱。

        Error_line() as ErrorLine,  --發生錯誤的行號

        Error_message() as ErrorMessage  --錯誤的具體信息

   if(@@trancount>0) --全局變數@@trancount,事務開啟此值+1,他用來判斷是有開啟事務

      rollback tran  --出錯回滾,A表中0條數據

     -- rollback tran pigOneIn  --出錯回滾,A表中1條數據

end catch

if(@@trancount>0)

commit tran

SELECT * FROM A   --如果成功A表中,將會有3條數據。

5.使用set xact_abort

 指定是否回滾當前事務(xact_abort on/off) , 為on時,如果當前sql出錯,回滾整個事務,為off時,如果sql出錯回滾當前sql語句,其它語句照常運行讀寫資料庫。

註意:xact_abort只對運行時出現的錯誤有用,如果sql語句本身存在錯誤,那麼xact_abort就沒用了。

示例:

set xact_abort off

begin tran

   insert into A(id,name,typeid) values (1,'小王',1)     --語句正確

   insert into A(id,name,typeid) values (2,'小李',12313212313212313)    --算術溢出錯誤,將插入其他兩條。如果這裡是'學生', xact_abort將失效,不插入任何數據

   insert into A(id,name,typeid) values (1,'小張',2)     --語句正確

commit tran

select * from A

6.事物併發

在多用戶都用事務同時訪問同一個數據資源的情況下,就會造成以下幾種數據錯誤。

更新丟失:多個用戶同時對一個數據資源進行更新,必定會產生被覆蓋的數據,造成數據讀寫異常。

不可重覆讀:如果一個用戶在一個事務中多次讀取一條數據,而另外一個用戶則同時更新啦這條數據,造成第一個用戶多次讀取數據不一致。

臟讀:第一個事務讀取第二個事務正在更新的數據表,如果第二個事務還沒有更新完成,那麼第一個事務讀取的數據將是一半為更新過的,一半還沒更新過的數據,這樣的數據毫無意義。

幻讀:第一個事務讀取一個結果集後,第二個事務,對這個結果集經行增刪操作,然而第一個事務中再次對這個結果集進行查詢時,數據發現丟失或新增

我們用鎖定正在操作的數據,來解決這些問題,當一個事務對一些數據塊進行操作的時候,另外一個事務則不能插足這些數據塊。

鎖定從資料庫角度看大致可以分為6種:

共用鎖(S):用於讀操作(SELECT),還可以叫它讀鎖。多個事務可以併發讀取數據,但任何事務都不能修改數據,直到數據讀取完成,共用鎖釋放。S鎖通常數據被讀取完畢,立即被釋放。

排它鎖(X):用於寫操作( INSERT、DELETE),還可以叫他獨占鎖、寫鎖。僅允許一個事務處理數據,也就是說如果你對數據資源進行增刪改的操作時,其它任何事務不允許操作這塊資源,直到排它鎖被釋放,防止同時對同一資源進行多重操作。X鎖一直到事務結束才能被釋放。

更新鎖(U):用來預定要對此頁施加X鎖,它允許其它事務讀,但不允許再施加U。U鎖是為了防止出現死鎖模式,當兩個事務對一個數據資源進行先讀取在修改的情況下,使用共用鎖和排它鎖有時會出現死鎖現象,而使用更新鎖則可以避免死鎖的出現。資源的更新鎖一次只能分配給一個事務,如果需要對資源進行修改,更新鎖會變成排他鎖,否則變為共用鎖。U鎖一直到事務結束時才能被釋放。

意向鎖:SQL Server需要在層次結構中的底層資源上(如行,列)獲取共用鎖,排它鎖,更新鎖。例如表級放置了意 向共用鎖,就表示事務要對錶的頁或行上使用共用鎖。在表的某一行上上放置意向鎖,可以防止其它事務獲取其它不相容的的鎖。意向鎖可以提高性能,因為數據引 擎不需要檢測資源的每一列每一行,就能判斷是否可以獲取到該資源的相容鎖。意向鎖包括三種類型:意向共用鎖(IS),意向排他鎖(IX),意向排他共用鎖 (SIX)。

架構鎖:防止修改表結構時,併發訪問的鎖。

大容量更新鎖:允許多個線程將大容量數據併發的插入到同一個表中,在載入的同時,不允許其它進程訪問該表。

 

這些鎖之間的相互相容性,也就是,是否可以同時存在。

   現有的授權模式     
 請求的模式  IS  S  U  IX  SIX  X
 意向共用 (IS)  是  是  是  是  是  
 共用 (S)  是  是  是      
 更新 (U)  是  是        
 意向排他 (IX)  是      是    
 意向排他共用 (SIX)  是          
 排他 (X)            

 

 

 

 

 

 

 

 

7.死鎖

死鎖是指在一組進程中的各個進程均占有不會釋放的資源,但因互相申請被其他進程所站用不會釋放的資源而處於的一種永久等待狀態。

減少死鎖的方法大致有一下幾種:

按同一順序訪問對象:併發事務按同一順序訪問對象,則發生死鎖的可能性會降低。

保持事務簡短:儘量不要讓一個事務處理過於複雜的讀寫操作,事務過於複雜,占用資源會增多,處理時間增長,併發執行事物通常會發生死鎖。

避免事務中的用戶交互:儘量不要在事務中要求用戶響應,因為事務持有的任何鎖只有在事務提交或回滾後才會釋放,等待用戶響應的時間,容易導致阻塞或死鎖。

減少併發量及占用時間長的數據操作:儘量減少資料庫的併發量,減少事務長時間等待。

使用較低的隔離級別:使用較低的隔離級別比使用較高的隔離級別持有共用鎖的時間更短。這樣就減少了鎖爭用。註意:先確定事務是否能在較低的隔離級別上運行。

使用基於行版本控制的隔離級別:如果將 READ_COMMITTED_SNAPSHOT 資料庫選項設置為 ON,則在已提交讀隔離級別下運行的事務在讀操作期間將使用行版本控制而不是共用鎖。

8.為事務設置隔離級別

所謂事物隔離級別,就是併發事務對同一資源的讀取深度層次。分為5種。

read uncommitted:這個隔離級別最低啦,可以讀取到一個事務正在處理的數據,但事務還未提交,這種級別的讀取叫做臟讀。

read committed這個級別是預設選項,不能臟讀,不能讀取事務正在處理沒有提交的數據,但能修改。

repeatable read不能讀取事務正在處理的數據,也不能修改事務處理數據前的數據。

snapshot指定事務在開始的時候,就獲得了已經提交數據的快照,因此當前事務只能看到事務開始之前對數據所做的修改。

serializable最高事務隔離級別,只能看到事務處理之前的數據。

語法

set tran isolation level <級別>

示例1:read uncommitted

begin tran
  set deadlock_priority low
  update A set name='小王1' where id=1 --原數據小王
  waitfor  delay '0:0:5' --等待5秒執行下麵的語句
rollback tran

set tran isolation level read uncommitted
select * from A  --讀取的數據為正在修改的數據 ,臟讀
waitfor  delay '0:0:5'  --5秒之後數據已經回滾
select * from A --回滾之後的數據

得到 name='小王'。

示例2:read committed
begin tran
  update A set name='小王'
  waitfor  delay '0:0:10' --等待10秒執行下麵的語句
rollback tran

set tran isolation level read committed
select * from A --獲取不到A,不能臟讀
update A set name='小王2'  where id=1 --可以修改
waitfor  delay '0:0:10'  --10秒之後上一個事務已經回滾
select * from A--修改之後的數據,而不是A

得到 name='小王2'。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ...
  • 在Oracle中因為沒有top關鍵字,所以在sqlserver中的分頁代碼並不適用於Oracle,那麼在Oracle中如何來實現分頁呢? --查詢所有數據 比如說我要查詢stuInfo表中第二到第四條記錄 --兩層嵌套分頁 --如果我沒有對原始表有其他的排序操作的話,兩層嵌套就可以滿足需求了,但是如 ...
  • --創建一個新用戶NewUser 並設置密碼為1 create user NewUser identified by 1; --為該用戶賦予許可權 grant connect , Resource to NewUser; ...
  • Spark從1.6.0版本開始,記憶體管理模塊就發生了改變,舊版本的記憶體管理模塊是實現了StaticMemoryManager 類,現在被稱為"legacy"。"Legacy"模式預設被置為不可用,這就意味著當你用Spark1.5.x和Spark1.6.x運行相同的代碼會有不同的結果,應當多加註意。考 ...
  • 這是spark1.5及以前堆記憶體分配圖 下邊對上圖進行更近一步的標註,紅線開始到結尾就是這部分的開始到結尾 spark 預設分配512MB JVM堆記憶體。出於安全考慮和避免記憶體溢出,Spark只允許我們使用堆記憶體的90%,這在spark的spark.storage.safetyFraction 參數 ...
  • 一、介紹基本資料庫的埠號、 SQLServer 埠號:1433 MySql 埠號:3306 Oracle 埠號:1521 二、orcl的基礎介紹 1)什麼是orcl 是一款關係型(二維表)資料庫,可以用來存儲海量數據。在大數據量併發檢索的情況下,性能要高於其他的同類資料庫產品。一般運行環境是 ...
  • 安裝 配置資料庫 配置驅動 配置連接 配置驅動 配置連接 如果你的工作中,需要使用到多個資料庫,又不想在多種客戶端之間切換來切換去。那麼就需要找一款支持多資料庫的客戶端工具了。如果你要連接多個關係型資料庫,你就可以使用Navicat Premium。但是如果你有使用到NOSQL(譬如HBase、Mo ...
  • 當我看到sql執行很慢的時候就在想為什麼這麼慢? 不外乎數據大,sql語句複雜,沒有索引。 如果要進行優化的話可以從對應的這三個問題出發: 看看表是否可以進行拆分成小表,拆分sql語句,建立適合的索引。 還有查看sql server官方API文檔,瞭解sql的關鍵字執行順序,瞭解執行順序後才能更好的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...