77873


ASP.NET Core MVC（.NET 5）にて、単一のClientかつ、開いた1ページから複数のAjaxリクエストを実行しています。

Ajaxリクエストを受けるControllerにて、リクエスト毎に異なるキーのセッション書き込みを行っています。  
同一のClientから次のリクエストを行った際にセッションの状態を確認すると、ひとつのキーのみが書き込まれている状態です（場合によってはふたつになることもありますが）。

単一のClientから異なるキーのセッション情報を書き込んだのですからセッションは同一のものが使われ、キーの競合は発生していないので、すべてのキーが書き込まれて欲しいと考えています。

Microsoftのドキュメントでは次のように書いてあります。

<https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/app-
state?view=aspnetcore-5.0#session-options>

> セッション状態は "ロックなし" です。 2 つの要求がセッションの内容を同時に変更しようとした場合、最後の要求が最初の要求をオーバーライドします。
> Session は 一貫性のあるセッション として実装されます。つまり、コンテンツは全部まとめて保管されます。 2
> つの要求が異なるセッション値を変更しようとしたとき、最後の要求が最初の要求によって行われたセッションの変更をオーバーライドすることがあります。

つまり、セッションでは同時リクエストによるキーの同時書き込みはできないという結論になるでしょうか？もし、そうであるとすればセッションの代わりにどのような仕組みを使えばよいでしょうか？

Controllerのコード例

[code]

        public async Task<IActionResult> SessionSet01Async()
        {
            await HttpContext.Session.LoadAsync();
            HttpContext.Session.SetString("key01", "001");
            Thread.Sleep(1);
            await HttpContext.Session.CommitAsync();
            return Content("");
        }
        public async Task<IActionResult> SessionSet02Async()
        {
            await HttpContext.Session.LoadAsync();
            HttpContext.Session.SetString("key02", "002");
            Thread.Sleep(1);
            await HttpContext.Session.CommitAsync();
            return Content("");
        }
        public async Task<IActionResult> SessionSet03Async()
        {
            await HttpContext.Session.LoadAsync();
            HttpContext.Session.SetString("key03", "003");
            Thread.Sleep(1);
            await HttpContext.Session.CommitAsync();
            return Content("");
        }
        public async Task<IActionResult> SessionSet04Async()
        {
            await HttpContext.Session.LoadAsync();
            HttpContext.Session.SetString("key04", "004");
            Thread.Sleep(1);
            await HttpContext.Session.CommitAsync();
            return Content("");
        }
    
[/code]

`LoadAsync()`及び`CommitAsync()`は、無くても同じ結果です。  
`Thread.Sleep(1)`は同時実行となるように追加しています。

[code]

        <script src="~/lib/jquery/dist/jquery.min.js"></script>
        <script>
            $(function () {
                $.get('/SetSession/SessionSet01');
                $.get('/SetSession/SessionSet02');
                $.get('/SetSession/SessionSet03');
                $.get('/SetSession/SessionSet04');
            });
        </script>
    
[/code]


CC BY-SA 4.0
2021-06-25T02:18:26.107
77772
2021-06-30T02:10:18.783
2021-06-30T02:10:18.783
3060
8647
question
c# mvc asp.net-core session
ASP.NET Core MVC で単一クライアントからの同時セッション書き込みは可能か？


Microsoftのドキュメントの通り、下図のような状態でセッションデータが更新される。セッションはキー毎ではなくセッションデータ全体をまとめて保存する仕様のため同時リクエストでの書き込みはできない。

[![セッションの更新状態](https://i.stack.imgur.com/8bHiP.png)](https://i.stack.imgur.com/8bHiP.png)

同時リクエストで一時データの保存を行いたい場合は、RDB, Memcached,
Redisなどの別のデータストアを用いる。（Sessionプロバイダーとしてではなく、独立したCacheとして用いる）

※この内容が間違っていた場合はご指摘ください。


CC BY-SA 4.0
2021-06-30T02:08:35.147
77873
2021-06-30T02:08:35.147
8647
77772
answer