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

