Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何避免ASP.NET SqlServer会话干扰每个请求的环境事务?_Asp.net_Session State_Transactions - Fatal编程技术网

如何避免ASP.NET SqlServer会话干扰每个请求的环境事务?

如何避免ASP.NET SqlServer会话干扰每个请求的环境事务?,asp.net,session-state,transactions,Asp.net,Session State,Transactions,我试图在每个请求的事务模式中使用事务作用域。因此,我有一个http模块,可以(简化): 然后,在我的web.config中,我有: <httpModules> <clear/> <add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/> <add name="Session" type="System.Web.SessionState.SessionS

我试图在每个请求的事务模式中使用事务作用域。因此,我有一个http模块,可以(简化):

然后,在我的web.config中,我有:

<httpModules>
    <clear/>
    <add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
    <add name="Session" type="System.Web.SessionState.SessionStateModule"/>
    <add name="Profile" type="System.Web.Profile.ProfileModule"/>
    <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add name="TransactionPerRequestWebModule" type="Acme.Web.TransactionPerRequestWebModule, Acme.Web"/>
</httpModules>
<sessionState mode="SQLServer" sqlConnectionString="Data Source=localhost\SQLEXPRESS;Integrated Security=SSPI;" cookieless="false" timeout="360"/>
我(认为我)理解的是,到ASP.NET会话数据库的连接有时被登记在我的业务事务中,当我的业务事务首先完成时,我会出现此错误

这有几个问题:

  • 我认为会话状态的事务不应该与我的业务事务相同。这是两个不同的问题
  • 它使事务自动升级为分布式(MSDTC)事务,这会影响我的性能

    如何将业务事务与ASP.NET会话1分离

    提前感谢,

    朱利安


我不完全确定您的代码是如何工作的,但您可以像这样抑制环境事务,这可能会有帮助:

using(TransactionScope scope1 = new TransactionScope())
{
     try
     {
          //Start of non-transactional section 
          using(TransactionScope scope2 = new
             TransactionScope(TransactionScopeOption.Suppress))
          {
               //Do non-transactional work here
          }
          //Restores ambient transaction here
   }
     catch
     {}
   //Rest of scope1
}

这是一个死记硬背的回答,但是如果其他人在谷歌搜索时偶然遇到这个问题,那么答案是将
inclist=False
添加到
SqlServerSessionState连接字符串中

由于奇怪的时间安排,用于检索会话的连接有时可以登记到环境事务中,即使您可能希望它不登记


在连接字符串上设置
inclist=False
,可确保会话状态连接不会拾取环境事务,从而导致快速事务升级为较慢的分布式事务。

感谢您的回答,Balazs。我可能不太清楚。我需要一个商业交易,所以我不想抑制它。只是我需要它与ASP.NET会话不同。它只会在内部using块的范围内被抑制。因此,在该块中执行任何与会话相关的工作。与会话相关的工作仍将包含在事务中(scope2)。但是,内部事务中的故障不会影响外部事务。这就是“抑制”选项的全部功能。它只会导致包含事务的作用域忽略该代码块。我还是不明白你的问题吗?
[SqlException (0x80131904): Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.]
  System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1951450
  System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4849003
  System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194
  System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2394
  System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33
  System.Data.SqlClient.SqlDataReader.get_MetaData() +83
  System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +297
  System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954
  System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
  System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
  System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
  System.Data.SqlClient.SqlCommand.ExecuteReader() +89
  System.Web.SessionState.SqlSessionStateStore.DoGet(HttpContext context, String id, Boolean getExclusive, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actionFlags) +516

[HttpException (0x80004005): Unable to connect to SQL Server session database.]
  System.Web.SessionState.SqlSessionStateStore.ThrowSqlConnectionException(SqlConnection conn, Exception e) +229
  System.Web.SessionState.SqlSessionStateStore.DoGet(HttpContext context, String id, Boolean getExclusive, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actionFlags) +649
  System.Web.SessionState.SqlSessionStateStore.GetItemExclusive(HttpContext context, String id, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actionFlags) +48
  System.Web.SessionState.SessionStateModule.GetSessionStateItem() +117
  System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData) +487
  System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +66
  System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
using(TransactionScope scope1 = new TransactionScope())
{
     try
     {
          //Start of non-transactional section 
          using(TransactionScope scope2 = new
             TransactionScope(TransactionScopeOption.Suppress))
          {
               //Do non-transactional work here
          }
          //Restores ambient transaction here
   }
     catch
     {}
   //Rest of scope1
}