6

SQL Server のセッションに Microsoftの新しいUniversal Providersを使用しています。SQL Server でのセッションの古い実装では、期限切れのセッションをクリアするために (毎分実行される) ジョブが必要でした。新しいものは、このチェックを行い、リクエストごとにクリアします。私は実際に SQL Azure で実行しているので、ジョブをスケジュールするための SQL エージェントを持っていないので、これは合理的な方法のように思えます (いいえ、Azure Cache のセッションに料金を支払いたくありません)。

問題は、複数のユーザーが同時にサイトにアクセスすると、両方のユーザーが同時に期限切れの同じセッションをクリアしようとし、2 番目のユーザーが楽観的同時実行例外を取得することです。

System.Data.OptimisticConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
   at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter)
   at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
   at System.Web.Providers.DefaultSessionStateProvider.PurgeExpiredSessions()
   at System.Web.Providers.DefaultSessionStateProvider.PurgeIfNeeded()
   at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

エラー ログに ELMAH を使用していますが、これはある程度の頻度で表示されます。エラーを無視するように ELMAH を構成しようとする前に、そもそもエラーが発生しないようにする方法を知っている人はいますか? 不足している新しいプロバイダーの構成はありますか?

4

3 に答える 3

2

http://www.nuget.org/packages/System.Web.Providersから新しいバージョンのプロバイダーをダウンロードしてください。期限切れのセッションをクリーンアップして非同期に実行し、エラー状態を処理する方法を更新しました。問題が解決しない場合はお知らせください。

于 2012-06-25T17:29:56.440 に答える
1

このパッケージには、私がバグとして説明するものが含まれています。アウトプロセスセッション状態の前提は、複数のインスタンスがセッション状態のクリーンアップを管理している可能性があることです。この場合、すべてのインスタンスがこのメソッドを実行しています...

private void PurgeExpiredSessions()
{
    using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString))
    {
        foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities))
        {
            entities.DeleteObject(entity);
        }
        entities.SaveChanges();
        this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks;
    }
}

問題は、一方のインスタンスがもう一方のインスタンスよりも先にエンティティを削除し、エンティティが投稿に記載されているエラーをスローすることです。パッケージの作成者にソースコードをリリースするか、これを修正するように依頼しました。テストされていないテキストエディタの修正は、パブリック仮想を追加することであるため、メソッドをオーバーライドするか、単に変更することもできます。

private void PurgeExpiredSessions()
{
    using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString))
    {   
        var sqlCommand = @"DELETE dbo.Sessions WHERE Expires < GETUTCDATE()";
        entities.ExecuteStoreCommand(sqlCommand);
        this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks;
    }
}

パッケージの作者は非常に迅速に応答し(これを投稿している間に回答しました!)、今日、彼らはコードのリリースに取り組んでいるが、これを修正できるかもしれないと述べました。私はETAをリクエストしましたが、入手した場合はここでフォローアップを試みます。

素晴らしいパッケージです。少しのメンテナンスが必要です。

適切な回答:ソースコードのリリースまたは修正の更新を待ちます。または、自分で逆コンパイルして修正します(それがライセンスと一致している場合!)

*パッケージの所有者が今週修正を検討している更新。うん!* * Update.SOLVED !!! 彼らは明らかにそれをしばらく前に修正しました、そして私は間違ったパッケージをインストールしていました..私はhttp://nuget.org/packages/System.Web.Providersを使用していました、そして私はhttp://nuget.org/packages/使用するべきでしたMicrosoft.AspNet.Providers / ..どれがレガシーで、別のパッケージに含まれているかは私にはわかりませんでした。彼らはそれを空のキャッチで包んだ。

private void PurgeExpiredSessions()
{
    try
    {
        using (SessionEntities entities = ModelHelper.CreateSessionEntities(this.ConnectionString))
        {
            foreach (SessionEntity entity in QueryHelper.GetExpiredSessions(entities))
            {
                entities.DeleteObject(entity);
            }
            entities.SaveChanges();
            this.LastSessionPurgeTicks = DateTime.UtcNow.Ticks;
        }
    }
    catch
    {
    }
}

このような迅速な対応と素晴らしいサポートを提供してくれたパッケージチームに感謝します!!!

于 2013-02-04T19:19:18.443 に答える
1

これに関する質問をNuGet(http://www.nuget.org/packages/System.Web.Providers)に投稿し、所有者から非常に迅速な回答を得ました。少し前後に移動した後、これに対する修正が行われていることがわかりましたが、次のアップデートで公開されます。

ここで、Microsoftはこれをサポートすることにあまり熱心ではないという提案がありましたが、私の経験はそうではなく、常に良いサポートを受けてきました。

于 2012-06-28T17:13:56.787 に答える