SQL Server數據庫高級進階之事務實戰演練

1、SQL Server事務的本質

•  什麼是SQL Server數據庫事務?
事務:
是做爲單個工做單元而執行的--系列操做,如查詢和修改數據,甚至多是修改數據定義。
事務:保持邏輯數據一致性與可恢復性,必不可少的利器。

•  SQL Server數據庫事務舉例
在一個事務中,你寫了2條sql語句,一條是修改訂單表狀態,一條是修改庫存表庫存-1 。 若是在修改訂單表狀態的時候出錯,事務可以回滾,數據將恢復到沒修改以前的數據狀態,下面的修改庫存也就不執行,這樣確保你關係邏輯的一致,安全。html

• 阿笨對SQL Server事務一句話總結
即這一組命令要麼都執行,要麼都不執行,通俗的理解就是共同進退。sql

2、SQL Server事務分類

SQL Server定義事務邊界的方式分爲顯式事務隱式事務兩種。

•  顯式事務:明確指出事務的起止邊界。若是不顯式定義事務的邊界,SQL Server 會默認把每一個單獨的語句做爲-一個事務;換句話說,SQLServer默認在執行完每一個語句以後就自動提交事務。

顯示事務須要定義以BEGIN TRAN語句做爲開始。若是想提交事務,則應該以COMMIT TRAN語句顯式結束事務;若是不想提交事務(撤消事務中的修改),則應該以ROLLBACK TRAN語句顯式結束事務。

•  隱式事務:SQL查詢分析器中,當前會話默認就是爲隱式事務。每執行一條DML操做,就直接提交到數據庫保存。數據庫

3、SQL Server事務的小陷阱

下面的例子將兩個INSERT語句封裝在由BEGIN TRAN和COMMIT TRAN定義的一個顯示事務邊界中:安全

BEGIN TRAN;性能優化

INSERT INTO dbo. T1(keyco], col1, co12) VALUES(4, 101,'C);服務器

INSERT INTO dbo. T1(keyco], col1, co12) VALUES(4, 101,'C);微信

COMMIT TRAN;併發

T-SQL使用下列語句來管理完整的事務(事務的基本三要素):app

•  開始事務:BEGIN TRANSACTIONide

•  提交事務:COMMIT TRANSACTION

•  回滾(撤銷)事務:ROLLBACK TRANSACTION

•  存儲點語句:SAVE TRANSACTION(可選)

所謂事務存儲點就是在事務過程中插入若干個標記,當事務執行中出現錯誤時,能夠不撤銷整個事務,只是撤銷部分事務,將事務退回到某個事物存儲點。一旦事務提交或回滾,則事務結束。(備註:將事務回滾在初始狀態成本有點大,那麼關於事務使用存儲點根據實際業務狀況來斷定是否使用。)

•   阿笨我的總結:
默認的隱式事務,在SQL Server查詢分析器中每個單獨的語句就是一個事務,若是多行語句塊須要包裹在一個事務中的話,則須要手動的開啓顯示事務。

(2條消息)SQL Server中的事務(附有實例)_數據庫_legendaryhaha的博客-CSDN博客 https://blog.csdn.net/legendaryhaha/article/details/80550180?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

4、SQL Server事務的特性

事務必須有四個屬性:原子性(Atomicity)、一致性 (Consistency)、隔離性(Isolation)、持久性(Durability) ,這4個屬性的首字母能夠縮寫爲ACID。

1240

A帳號向B帳號轉帳200

•  原子性(Atomicity)

原子性是指事務是一個不可分割的工做單位,事務中的操做要麼都發生,要麼都不發生。

針對同一個事務

操做前A:800,B:200

操做後A:600,B:400

一致性表示事務完成後,符合邏輯運算。

•  一致性(Consistency)

事務先後數據的完整性必須保持一致。

針對一個事務操做前與操做後的狀態一致

操做前A:800,B:200

操做後A:600,B:400

一致性表示事務完成後,符合邏輯運算

•  隔離性(Isolation)

事務的隔離性是多個用戶併發訪問數據庫時,數據庫爲每個用戶開啓的事務,不能被其餘事務的操做數據所幹擾,多個併發事務之間要相互隔離。

針對多個用戶同時操做(兩個事務同時進行),主要是排除其餘事務對本次事務的影響。

即不一樣事務之間的相互影響和隔離的程度。好比,不一樣的隔離級別,事務的併發程度也不一樣,最強的隔離狀態是全部的事務都是串行化的(serializable)(即一個事務完成以後才能進行下一個事務),這樣併發性也會降到最低,在保證了強一致性的狀況下,性能也會受很大影響,因此在實際工程當中,每每會折中一下。每一個RMDB關係型數據庫的事務默認隔離級別是不同的。

•  持久性(Durability)

持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即便數據庫發生故障也不該該對其有任何影響。

SQL SERVER經過write-ahead transaction log來保證持久性。write-ahead transaction log的意思是,事務中對數據庫的改變在寫入到數據庫以前,首先寫入到事務日誌中。而事務日誌是按照順序排號的(LSN)。當數據庫崩潰或者服務器斷點時,重啓動SQL SERVER,SQL SERVER首先會檢查日誌順序號,將本應對數據庫作更改而未作的部分持久化到數據庫,從而保證了持久性.。

表示事務結束後的數據不隨着外界緣由致使數據丟失

操做前A:800,B:200

操做後A:600,B:400

若是在操做前(事務尚未提交)服務器宕機或者斷電,那麼重啓數據庫之後,數據狀態應該爲

A:800,B:200

若是在操做後(事務已經提交)服務器宕機或者斷電,那麼重啓數據庫之後,數據狀態應該爲

A:600,B:400

5、SQL Server事務的隔離級別

1)、什麼是數據庫隔離級別

數據庫的隔離級別其實是針對事務的隔離級別來講的,它是用來限制一個事務中正在讀取或被修改的數據免於被其餘事務修改的程度。理論上每一個事務和其餘的事務都應該徹底隔離開來。然而出於性能和可行性的緣由,實踐中幾乎不可能作到的。

2)、數據庫爲何要有事務的隔離級別

在併發環境下若是沒有鎖和隔離級別, 不考慮事務的隔離性可能引起的問題 可能會發生如下四種狀況:

髒讀:在這種狀況下,一個事務可以讀取另外一個事務正在修改且未提交的數據,那麼另外一個事務若是發生回滾操做,將致使第一個事務讀取到的數據和實際的數據不一致;

丟失更新:這種狀況下,事務沒有隔離。多個事務可以讀取同一份數據而且修改它。最後對數據集作出修改的事務將勝出,而其餘的事務所作的修改都失效;

不可重複讀:兩個事務讀取數據,可是在第二個事務讀取前,另外一個事務修改了該數據,所以兩次讀取的數據不一致;

幻讀:這種狀況和不可重複讀相似,不一樣的是,兩個事務讀取一個範圍的數據,可是在第二個事務讀取以前,另外一個事務新增了一條數據,致使兩次讀取的結果不一樣。

要想解決髒讀、不可重複讀、幻讀等讀現象,那麼就須要提升事務的隔離級別。但與此同時,事務的隔離級別越高,併發能力也就越低。因此,還須要讀者根據業務須要進行權衡。 

在瞭解了併發狀況下出現的上述問題後,就能夠進一步理解隔離級別的概念,通俗一點講就是:你但願以何種方式將併發的事務隔離開來, 隔離到什麼程度?好比容許髒讀,等。隔離級別越高,讀取髒數據或者形成數據不一致的狀況就越少,可是在高併發系統中的性能下降就越嚴重。

2)、Sql Server支持6種隔離級別

•  未提交讀(Read Uncommited)

•  已提交讀(Read Commited)(Sql Server的默認事務隔離級)

•  可重複讀(Repeatable Read)

•  序列化(Serializable)

•  快照(Snapshot)

•  已提交讀快照(Read Commited Snapshot)

查看SQL Server當前會話的隔離級別 

DBCC USEROPTIONS  

Sql Server的默認事務隔離級別是已提交讀(Read Commited),一個事務不容許讀取另外一個事務未提交的數據。

Mysql默認的事務處理級別是可重複讀(Repeatable Read)也就是可重複讀。

Oracle默認系統事務隔離級別是已提交讀(Read Commited),也就是讀已提交。

備註:實際工做中通常數據庫默認的事務隔離級別作好不要去作修改。

6、SQL Server事務的實戰運用場景

1)、批量一次性提交事務處理數據(插入)。

一)、爲何一次性提交事務批量插入數據效率最高?

使用事務能夠提升數據的插入效率,這是由於進行一個INSERT操做時,SQL SERVER內部會創建一個事務,在事務內才進行真正插入處理操做。經過使用事務能夠減小建立事務的消耗,全部插入都在執行後才進行提交操做。

二)、關於批量插入大數據的帶來的思考總結

•  爲了提高效率,數據能一次提交不作屢次提交;

•  能一次插入解析sql不要屢次提交解析sql;

•  插入數據量太大時,須要程序預先切割數據;

2)、在事務範圍中如何防止查詢大面積的數據行內出現死鎖的狀況

要提高SQL的查詢效能,通常來講你們會以創建索引(index)爲第一考慮。其實除了index的創建以外,當咱們在下SQL Command時,在語法中加一段WITH (NOLOCK)能夠改善在線大量查詢的環境中數據集被LOCK的現象藉此改善查詢的效能。

鎖爭用的解決方法:SQL Server開始是用行級鎖的,可是常常會擴大爲頁面鎖和表鎖,最終形成死鎖。 幸運的是,咱們能夠經過SQL Server 的NOLOCK來手工處理。

NOLOCK的使用
NOLOCK能夠忽略鎖,直接從數據庫讀取數據。這意味着能夠避開鎖,從而提升性能和擴展性。不過有一點千萬要注意的就是,WITH (NOLOCK)的SQL SELECT有可能會形成Dirty Read,就是讀到無效的數據。

SQLServer性能優化之 nolock,大幅提高數據庫查詢性能 - 雲霏霏
 http://www.javashuo.com/article/p-koljamfa-t.html

7、SQL Server事務遵照原則

編寫事務時要遵照的原則大概總結以下:

•  事務儘量簡短:

  事務啓動至結束後再數據庫管理系統中保留大量資源,以保證事務的原子性、一致性,隔離性和持久性。若是在多用戶系統中,較大的事務將會佔用系統的大量資源,是系統不堪重負,會影響軟件的性能,甚至致使系統崩潰。

•  事務中訪問的數據量儘可能最少:

  當併發執行事務處理時,事務操做的數據量越少,事務之間對操做數據的爭奪就越少。

•  查詢數據時儘可能不要使用事務:

  對數據進行瀏覽查詢操做並不會更新數據庫的數據,所以儘可能不使用事務查詢數據,避免佔用過量的系統資源。

•  在事務處理過程當中儘可能不要出現等待用戶輸入的操做:

   在處理事務的過程當中,若是須要等待用戶輸入數據,那麼事務會長時間地佔用資源,有可能形成系統阻塞。

【網易雲課堂】:點擊在線觀看

【騰訊課堂】:點擊在線觀看

【微信公衆號】:跟着阿笨一塊兒玩NET

相關文章
相關標籤/搜索