.NET中 關(guān)于臟讀 不可重復(fù)讀與幻讀的代碼示例
并發(fā)可能產(chǎn)生的三種問題
臟讀
定義:A事務(wù)執(zhí)行過程中B事務(wù)讀取了A事務(wù)的修改,但是A事務(wù)并沒有結(jié)束(提交),A事務(wù)后來可能成功也可能失敗。
比喻:A修改了源代碼并且并沒有提交到源代碼系統(tǒng),A直接通過QQ將代碼發(fā)給了B,A后來取消了修改。
代碼示例
[TestMethod]
public void 臟讀_測試()
{
//前置條件
using (var context = new TestEntities())
{
Assert.AreEqual(1, context.Tables.Count());
}
var autoResetEvent = new AutoResetEvent(false);
var transactionOptions1 = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
var transactionOptions2 = new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted };
using (var ts1 = new TransactionScope(TransactionScopeOption.Required, transactionOptions1))
{
//添加數(shù)據(jù)
using (var context = new TestEntities())
{
context.Tables.Add(new Table() { Id = Guid.NewGuid(), Name = "段光偉" });
context.SaveChanges();
}
ThreadPool.QueueUserWorkItem(data =>
{
using (var ts2 = new TransactionScope(TransactionScopeOption.Required, transactionOptions2))
{
//臟讀測試
using (var context = new TestEntities())
{
Assert.AreEqual(2, context.Tables.Count());
}
}
autoResetEvent.Set();
});
autoResetEvent.WaitOne();
}
//前置條件
using (var context = new TestEntities())
{
Assert.AreEqual(1, context.Tables.Count());
}
}
不可重復(fù)讀
定義:A事務(wù)讀取了兩次數(shù)據(jù),在這兩次的讀取過程中B事務(wù)修改了數(shù)據(jù),A事務(wù)的這兩次讀取出來的數(shù)據(jù)不一樣了(不可重復(fù)讀)。
比喻:A在做源代碼審查,在審查的過程中獲取了兩次源代碼,在這兩次獲取期間B修改了源代碼,B修改的很可能是A審查過的代碼,而這部分代碼可能不符合規(guī)范了。
代碼示例
[TestMethod]
public void 不可重復(fù)讀_測試()
{
var autoResetEvent = new AutoResetEvent(false);
var transactionOptions1 = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
var transactionOptions2 = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (var ts1 = new TransactionScope(TransactionScopeOption.Required, transactionOptions1))
{
//前置條件
using (var context = new TestEntities())
{
Assert.AreEqual("李妞妞", context.Tables.First().Name);
}
ThreadPool.QueueUserWorkItem(data =>
{
using (var ts2 = new TransactionScope(TransactionScopeOption.Required, transactionOptions2))
{
//修改數(shù)據(jù)
using (var context = new TestEntities())
{
context.Tables.First().Name = "段光偉";
context.SaveChanges();
}
ts2.Complete();
}
autoResetEvent.Set();
});
autoResetEvent.WaitOne();
//不可重復(fù)讀測試
using (var context = new TestEntities())
{
Assert.AreEqual("段光偉", context.Tables.First().Name);
}
}
}
幻讀
定義:A事務(wù)讀取了兩次數(shù)據(jù),在這兩次的讀取過程中B事務(wù)添加了數(shù)據(jù),A事務(wù)的這兩次讀取出來的集合不一樣了(幻讀)。
比喻:A在統(tǒng)計文件數(shù)據(jù),為了統(tǒng)計精確A統(tǒng)計了兩次,在這兩次的統(tǒng)計過程中B添加了一個文件,A發(fā)現(xiàn)這兩次統(tǒng)計的數(shù)量不一樣(幻讀),A會感覺自己的腦袋有點頭疼。
代碼示例
[TestMethod]
public void 幻讀_測試()
{
var autoResetEvent = new AutoResetEvent(false);
var transactionOptions1 = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead };
var transactionOptions2 = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (var ts1 = new TransactionScope(TransactionScopeOption.Required, transactionOptions1))
{
//前置條件
using (var context = new TestEntities())
{
Assert.AreEqual(1, context.Tables.Count());
}
ThreadPool.QueueUserWorkItem(data =>
{
using (var ts2 = new TransactionScope(TransactionScopeOption.Required, transactionOptions2))
{
//添加數(shù)據(jù)
using (var context = new TestEntities())
{
context.Tables.Add(new Table() { Id = Guid.NewGuid(), Name = "段光偉" });
context.SaveChanges();
}
ts2.Complete();
}
autoResetEvent.Set();
});
autoResetEvent.WaitOne();
//幻讀測試
using (var context = new TestEntities())
{
Assert.AreEqual(2, context.Tables.Count());
}
}
}
四種隔離級別如何處理并發(fā)問題
| 臟讀 | 不可重復(fù)讀 | 幻讀 | |
| 讀未提交 | 允許 | 允許 | 允許 |
| 讀已提交 | 不允許 | 允許 | 允許 |
| 可重復(fù)讀 | 不允許 | 不允許 | 允許 |
| 串行化 | 不允許 | 不允許 | 不允許 |
相關(guān)文章
System.Data.SqlClient.SqlException: 無法打開登錄所請求的數(shù)據(jù)庫 登錄失敗。
今天幫客戶配置服務(wù)器的時間,安全設(shè)置后,將sqlserver以普通用戶權(quán)限運行的時候提示這個錯誤。2011-08-08
ASP.NET(C#) 讀取EXCEL另加解決日期問題的方法分享
這篇文章介紹了ASP.NET(C#) 讀取EXCEL另加解決日期問題的方法,有需要的朋友可以參考一下2013-11-11
MessagePack 和System.Text.Json 序列化和反序列化性能及對比分析
這篇文章主要介紹了MessagePack 和System.Text.Json 序列化和反序列化性能及對比分析,本文結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-01-01
點擊提交按鈕后DropDownList的值變?yōu)槟J值實現(xiàn)分析
在點擊提交按鈕后,頁面上所有的綁定到數(shù)據(jù)庫的控件值都恢復(fù)到默認值,下面與大家分享下DropDownList的值變?yōu)槟J值2013-05-05
Repeater綁定dictionary數(shù)據(jù)源代碼及報錯解決
為大家講解下Repeater綁定dictionary數(shù)據(jù)源以及報錯處理的方法,感興趣的朋友可以參考下哈,希望對你有所幫助2013-04-04
使用NLog給Asp.Net Core做請求監(jiān)控的方法
這篇文章主要介紹了使用NLog給Asp.Net Core做請求監(jiān)控的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
ASP.Net頁尾中添加JavaScript的最佳方法實戰(zhàn)分享
將JavaScript腳本或庫添加到asp.net頁的末尾方法有很多,究竟哪一個最好使呢有利于日后的維護啊,是個疑點啊,本文的出現(xiàn)將幫你解決所有的困惑,感興趣的你可不要錯過了哈2013-02-02

