Я пытаюсь использовать область транзакции в шаблоне транзакции за запрос. Таким образом, у меня есть модуль HTTP, которые (упрощенный):Как избежать сеанса ASP.NET SqlServer для вмешательства в окружающий транзакционный запрос?
private void Application_BeginRequest(object sender, EventArgs e)
{
var scope = new TransactionScope(TransactionScopeOption.RequiresNew);
PutScopeInHttpContext(scope);
}
private void Application_EndRequest(object sender, EventArgs e)
{
var scope = GetScopeFromHttpContext();
try
{
if (HttpContext.Current.Error == null)
{
scope.Complete();
}
}
finally
{
scope.Dispose();
}
}
Тогда в моем 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"/>
Теперь, что кажется случайным скоростью, примерно 1 страница из из десяти дает мне следующую ошибку:
[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
То, что я (думаю, I) понять, что подключение к базе данных сеанса ASP.NET иногда зачислен в моей бизнес-операции, и я получаю эту ошибку, когда мой бизнес-операции я сначала заканчивается.
Существует несколько проблем с этим:
- Я не думаю, что сделка для состояния сеанса должна быть такой же, как мой бизнес один. Это две отдельные проблемы.
Он автоматически переводит транзакцию в распределенный (MSDTC), что влияет на мою производительность.
Как отделить бизнес-транзакцию от сеанса ASP.NET?
Спасибо заранее,
Julien
Спасибо за ваш ответ, Балаз. Возможно, я не знаю. Мне нужна деловая сделка, поэтому я не хочу ее подавлять. Просто мне нужно, чтобы он отличался от сеанса ASP.NET. – Julien
Это будет только подавлено в рамках этого внутреннего блока использования. Итак, выполняйте любую работу, связанную с сеансом, которую вы должны делать в этом блоке. Работа, связанная с сеансом, по-прежнему будет охватываться транзакцией (scope2). Однако отказ во внутренней транзакции не повлияет на внешнюю транзакцию. Это вариант «Подавить». Это просто заставляет содержащую область транзакции игнорировать этот блок кода. Я все еще не понимаю ваш вопрос? – balazs