我想知道 TransactionScope 类如何工作以保持不同方法调用之间的事务(无需将其作为参数传递),我产生了这个疑问。关于这个问题,我有两个考虑:
1
通过 Telerik JustDecompile 查看 TransactionScope 的实现,我发现当前事务存储在 System.Transactions.ContextData 类的 ThreadStatic 成员中(代码如下)。
internal class ContextData
{
internal TransactionScope CurrentScope;
internal Transaction CurrentTransaction;
internal DefaultComContextState DefaultComContextState;
[ThreadStatic]
private static ContextData staticData;
internal WeakReference WeakDefaultComContext;
internal static ContextData CurrentData
{
get
{
ContextData contextDatum = ContextData.staticData;
if (contextDatum == null)
{
contextDatum = new ContextData();
ContextData.staticData = contextDatum;
}
return contextDatum;
}
}
public ContextData()
{
}
}
CurrentData 属性由 TransactionScope 的 PushScope() 方法调用,最后一个属性被大多数 TransactionScope 构造函数使用。
private void PushScope()
{
if (!this.interopModeSpecified)
{
this.interopOption = Transaction.InteropMode(this.savedCurrentScope);
}
this.SetCurrent(this.expectedCurrent);
this.threadContextData.CurrentScope = this;
}
public TransactionScope(TransactionScopeOption scopeOption)
{
// ...
this.PushScope();
// ...
}
好的,我想我已经找到了他们是如何做到的。
2
我已经了解了使用 ThreadStatic 成员在 ASP.NET (http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx) 中存储对象有多糟糕,因为可能会发生 ASP.NET 线程切换,所以这个数据可能会在工作线程中丢失。
所以,看起来 TransactionScope 不应该与 ASP.NET 一起工作,对吧?但就我在我的 Web 应用程序中使用它而言,我不记得我遇到过有关事务数据丢失的任何问题。
我的问题是“TransactionScope 处理 ASP.NET 线程切换的技巧是什么?”。
是不是对 TransactionScope 是如何存储其事务对象进行了粗浅的分析?或者 TransactionScope 类没有与 ASP.NET 一起工作,我可以被认为是一个从未为此感到痛苦的幸运儿?
任何知道 .NET 的“深埋秘密”的人都可以为我解释一下吗?
谢谢