.Net系列 Transaction 事務

Transactions

事務(Transaction),通常是指要作的或所作的事情。在計算機術語中是指訪問並可能更新數據庫中各類數據項的一個程序執行單元(unit)。在計算機術語中,事務一般就是指數據庫事務。數據庫

應用場景:

應用程序須要執行多個操做,包括一個或多個數據庫命令
* 其中一個數據庫命令失敗或某些其餘操做失敗(例如註冊表更新)
* 多項行動是爲了一塊兒工做。應用程序如今處於不一致的狀態。
咱們使用 transaction 來解決這個問題,transaction 就是執行所需的一組命令原子操做
➢若是全部命令都成功完成,則 transaction 成功。
➢若是有任何命令失敗,整個 transaction 將 rollback 到 pre-transaction 狀態。
➢形成rollback的故障不必定與數據庫相關。併發

ACID transaction properties 屬性

All database management systems adhere to a set of properties known as the ACID properties:
並不是任意的對數據庫的操做序列都是數據庫事務。數據庫事務擁有如下四個特性,習慣上被稱之爲ACID特性ui

Atomicity: 「All or nothing.」 No partial success. Either the transaction succeeds in its entirety or it fails.
原子性(Atomicity):事務做爲一個總體被執行,包含在其中的對數據庫的操做要麼所有被執行,要麼都不執行。this

Consistency: Integrity constraints are met. Acceptable for inconsistency to occur during the transaction, but must be completely consistent upon completion.
一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變爲另外一個一致狀態。一致狀態的含義是數據庫中的數據應知足完整性約束。spa

Isolation: The extent to which other transactions can 「see」 changes made by other transactions while they are executing.
隔離性(Isolation):多個事務併發執行時,一個事務的執行不該影響其餘事務的執行。.net

Durability: Guarantees permanent survival of data after the commit is complete.
持久性(Durability):已被提交的事務對數據庫的修改應該永久保存在數據庫中3d

.NET 頁、XML Web services方法或 .NET Framework 類一旦被標記爲參與事務,它們將自動在事務範圍內執行。您能夠經過在頁、XML Web services 方法或類中設置一個事務屬性值來控制對象的事務行爲。特性值反過來肯定實例化對象的事務性行爲。所以,根據聲明特性值的不一樣,對象將自動參與現有事務或正在進行的事務,成爲新事務的根或者根本不參與事務。聲明事務屬性的語法在 .NET Framework 類、.NET 頁和 XML Web services 方法中稍有不一樣。orm

Isolation Level 事務隔離層級

A property of the TransactionScope object, specifying the degree of transaction isolation.
隔離級別定義了事務與事務之間的隔離程度。
隔離級別與併發性是互爲矛盾的:隔離程度越高,數據庫的併發性越差;隔離程度越低,數據庫的併發性越好。server

Serializable (highest): read, write, and range locks (if necessary) used until end of the transaction.
序列化:提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接着一個地執行,不能併發執行。僅僅經過「行級鎖」是沒法實現事務序列化的,必須經過其餘機制保證新插入的數據不會被剛執行查詢操做的事務訪問到。對象

RepeatableRead: Same, except no range locks. Other transactions can delete/update resulting in phantom reads.
可重複讀取:禁止不可重複讀取和髒讀取,可是有時可能出現幻讀數據。這能夠經過「共享讀鎖」和「排他寫鎖」實現。讀取數據的事務將會禁止寫事務(但容許讀事務),寫事務則禁止任何其餘事務。

Snapshot: Instead of write-locking, 「snapshot」 of to-be-written data is taken and served to reading transactions.
「snapshot」 取代 write-locking寫鎖定,獲取待寫入數據的 snapshot 並將其送達
reading transactions。這個實際上是tradeoff,並無複製全部的數據,
搞清楚OS中的 readlock,writelock, rangelock。
讀取數據時,能夠保證讀操做讀取的行是事務開始時可用的最後提交版本。這意味着這種隔離級別能夠保證讀取的是已經提交過的數據,而且能夠實現可重複讀,也能確保不會幻讀。

ReadCommitted: No dirty reads (not-yet-committed data from other transactions not visible), but non-repeatable reads may occur. (Default IL for SQL Server)
受權讀取:在commit以前,不容許dirty read(還沒有提交的其餘交易數據不可見)。但可能會發生不可重複的讀取,由於反覆讀取會有不同的結果。 (SQL Server的默認level)容許不可重複讀取,但不容許髒讀取。這能夠經過「瞬間共享讀鎖」和「排他寫鎖」實現。讀取數據的事務容許其餘事務繼續訪問該行數據,可是未提交的寫事務將會禁止其餘事務訪問該行。

ReadUncommitted (lowest): Dirty reads permitted. One transaction can see another transaction’s changes before the commit.
未受權讀取: 容許髒讀,但不容許更新丟失。若是一個事務已經開始寫數據,則另一個事務則不容許同時進行寫操做,但容許其餘事務讀此行數據。該隔離級別能夠經過「排他寫鎖」實現。無論事務B什麼時候Commit,事務A中的SELECT語句2均可以讀出數據(有多是髒數據,因事務B可能會ROLLBACK),且與語句1的數據不一樣。

 

Isolation Levels Illustrated

這個圖按照時間順序,上至下操做。
1. UnCommitted level時,只要A作出了更改,B就會讀取到這個更改,不存在Commit的考慮。

Committed level時,T1讀取了數據A,T2獲得同樣數據A。T1把數據修改成數據B,T2再讀取依然是數據A。commit以後,T2 就會獲得數據B。不可重複讀。

RepeatableRead和Serializable level時,區別在於Range Lock。T2 在commit以前,讀取的都是未修改的數據A。

選擇什麼level不少程度上取決於咱們對數據變化的重視程度。

 

下面是個例子:

 

關於 三種 讀

髒讀 :髒讀就是指當一個事務正在訪問數據,而且對數據進行了修改,而這種修改尚未提交到數據庫中,這時,另一個事務也訪問這個數據,而後使用了這個數據。

不可重複讀 :是指在一個事務內,屢次讀同一數據。在這個事務尚未結束時,另一個事務也訪問該同一數據。那麼,在第一個事務中的兩 次讀數據之間,因爲第二個事務的修改,那麼第一個事務兩次讀到的的數據多是不同的。這樣就發生了在一個事務內兩次讀到的數據是不同的,所以稱爲是不 可重複讀。例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,做者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重複。若是 只有在做者所有完成編寫後編輯人員才能夠讀取文檔,則能夠避免該問題。

幻讀 : 幻讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,好比這種修改涉及到表中的「所有數據行」。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入「一行新數據」。那麼,之後就會發生操做第一個事務的用戶發現表中還存在沒有修改的數據行,就好象發生了幻覺同樣.通常解決幻讀的方法是增長範圍鎖RangeS,鎖定檢索範圍爲只讀,這樣就避免了幻讀。

最高隔離級別SERIALIZABLE_READ能夠保證不出現幻讀的問題。

 

Transactions in EF

在Entity Framework中使用 transaction 更容易:事務自動發生在同一個事務中上下文。

SaveChanges 就自動有了transaction,是readcommitted level。
* Transactions using this technique are limited to the scope of the context in the using clause
* Transactions spanning multiple contexts require heavier artillery: TransactionScope
- You must add the reference System.Transactions
* Connecting to multiple databases requires enabling MSDTC on the server.

 

在EF版本6中:


SaveChanges以後還要Commit。
Try block以後Catch,任何問題發生均可以rollback。

 

若是咱們但願用其餘level的isolation,則須要用TransactionScope object:
這裏有 TransactionScope constructor。
須要兩個參數,一個是new,一個是transaction option object 設置 isolation level,這裏設置成最低的 Uncommitted。

下面的例子並未完成,由於沒有rollback

 

Change tracking

當修改EF對象或從容器中添加/刪除EF對象時…
* Changes are tracked locally by the context
* You can stop change tracking by detaching an entity from the context. (example to follow)

Calling SaveChanges does the following:
* Generates and executes SQL commands 生成並執行SQL命令
* Commits changes to the database in a single transaction 在單個事務中提交對數據庫的更改
* Resets tracking information重置跟蹤信息

改變跟蹤 attaching/detaching 例子


c2 脫離了,改變再也不被記錄。Savechanges時,只有c1 會被記載,c2仍是會被放在course的container裏,在Course裏仍是能夠看見c1和c2,可是數據庫裏只有c1。

--------------------- 原文:https://blog.csdn.net/CheungKaiwei/article/details/79775156 做者:CheungKaiwei 

相關文章
相關標籤/搜索