J'essaie d'utiliser une étendue de transaction dans un modèle de transaction par requête. J'ai donc un module http qui ne (simplifié):Comment éviter une session ASP.NET SqlServer d'interférer avec la Transaction-Per-Request ambiante?
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();
}
}
Puis, dans mon web.config, je:
<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"/>
Maintenant, à ce qui apparaît comme taux au hasard, à peu près 1 page sur dix me donne l'erreur suivante:
[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
ce que je (crois) comprendre est que la connexion à la base de données de session ASP.NET est parfois enrôlé dans ma transaction commerciale, et je reçois cette erreur lorsque ma transaction commerciale je s terminer en premier.
Il y a quelques problème avec ça:
- Je ne pense pas que la transaction pour l'état de session doit être le même que mon seul d'affaires. Ce sont deux préoccupations distinctes.
Il fait automatiquement remonter la transaction à une transaction distribuée (MSDTC), ce qui affecte mes performances. Comment puis-je découpler ma transaction commerciale de la session ASP.NET?
Merci à l'avance,
Julien
Merci pour votre réponse, Balazs. Je n'ai peut-être pas été clair. J'ai besoin d'une transaction commerciale, donc je ne veux pas la supprimer. C'est juste que j'ai besoin d'être différent de celui de la session ASP.NET. – Julien
Il ne serait supprimé que dans le cadre de ce bloc d'utilisation interne. Alors, faites ce que vous avez à faire dans ce bloc. Le travail lié à la session serait toujours couvert par une transaction (scope2). Cependant, une défaillance dans la transaction interne n'affecterait pas la transaction externe. C'est tout ce que fait l'option "Supprimer". Cela provoque simplement l'ignorance de ce bloc de code par la portée de transaction contenant. Est-ce que je ne comprends toujours pas votre question? – balazs