我想知道TransactionScope类如何工作以保持不同方法调用之间的事务(不需要将其作为参数传递),我对此产生了怀疑。我对这个问题有两点考虑:
通过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();
// ...
}
好的,我想我已经找到了他们是如何做到的。
我已经读过使用ThreadStatic成员在ASP.NET中存储对象有多糟糕(http://www.hanselman.com/blog/ATaleOfTwoTechniquesTheThreadStaticAttributeAndSystemWebHttpContextCurrentItems.aspx),因为可能发生ASP.NET线程切换,所以这些数据可能会在工作线程中丢失。
因此,看起来TransactionScope不适用于ASP.NET,对吧?但到目前为止,我已经在我的网络应用程序中使用它,我不记得有任何关于交易数据丢失的问题。
我的问题是“什么是TransactionScope处理ASP.NET线程切换的技巧?”。
我是否对TransactionScope如何存储其交易对象进行了肤浅的分析?或者,TransactionScope类不能与ASP.NET一起使用,我可以被认为是一个从未有过任何痛苦的幸运者吗?
知道.NET的“深埋秘密”的人能解释一下吗?
由于
答案 0 :(得分:1)
我认为ASP.NET线程切换仅在特定情况下(涉及asych IO操作)和请求生命周期的早期发生。通常,一旦控件传递给实际的http处理程序(例如,Page),线程就不会被切换。我相信在大多数情况下,事务范围将在此之后(在page_init / load之后)初始化,并且不应成为问题。
以下是您可能感兴趣的链接:
http://piers7.blogspot.com/2005/11/threadstatic-callcontext-and_02.html
http://piers7.blogspot.com/2005/12/log4net-context-problems-with-aspnet.html