2016-07-15 15 views
1

私はASP.NET MVC 6アプリケーションを持っています。ユーザーがクライアント側をAngularで入力すると、ASP.NETの非同期APIの呼び出しが行われます。いくつかの場所では、Apiを3-4回呼び出して他のリソースを取得します。同時に同じURLを複数回呼び出すと、EF 6の挿入がロックされます

また、私のデータベースにEF 6で接続されたUserテーブルを保持しています。ここで、(Windows Authを使用して)入力したユーザーが既に存在しない場合に新しいUser行を作成し、彼への役割

しかし、ユーザーがApiを3-4回呼び出すページを最初に入力すると、「作成」がテーブルをロックしていないため、ユーザーが3回作成されるため、ユーザーは3-4回作成されます。

次の呼び出しでロックが解除されるのを待ってから、そのユーザーが存在するかどうかを確認するために 'GetAsync'を実行するには、テーブル(私の場合はリポジトリ)をロックするにはどうすればよいですか?

3回呼び出されているコード:

 var currentUserName = User.Identity.Name; 
     var currentUser = await _userRepository.GetAsync(u => u.UserName == currentUserName); 

     // Create user that does not yet exist 
     if (currentUser != null) return HttpBadRequest(); 

     var user = new User(currentUserName); 

     using(new CreatedBySystemProvider(_userRepository)) 
     { 
      _userRepository.Add(user); 
      await _userRepository.SaveChangesAsync(); 
      await user.AddRoleAsync(AppSumRoles.Authenticated); 
      /* Temporary add SysAdmin role */ 
      if(string.Equals(currentUserName, @"BIJTJES\NilsG", StringComparison.CurrentCultureIgnoreCase)) 
      { 
       using(new CreatedBySystemProvider(_userRoleRepository)) 
       { 
        await user.AddRoleAsync(AppSumRoles.SysAdmin); 
       } 
      } 
      currentUser = await _userRepository.GetAsync(u => u.Id == user.Id); 
     } 

     return Ok(currentUser); 
+1

は、ユーザーの一意の識別子としてリクエストに何かを使用してください。 IPのようなもの –

+0

ユーザ名が一意でなければならない場合は、ユーザ名にユニークなインデックスを作成し、複数のパラレルリクエストが同じユーザを作成しようとする場合に例外を処理できます。 – grek40

答えて

0

別APIにCreateUserコードを移動することを検討してください。ユーザー作成は、別のユースケースでなければなりません。ユースケースの暗黙的な部分ではありません。心配しないでください。

0

ユーザーがプロセスを作成することを検討する必要があります。しかし、単にあなたの質問のためにあなたは、この

ような何かを行うことができます(詳細についてはPLSはhttp://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266988.aspxを参照)

private static readonly AsyncLock asyncLocker = new AsyncLock(); 

var currentUserName = User.Identity.Name; 

using(var releaser = await asyncLocker.LockAsync()) 
{ 
    var currentUser = await _userRepository.GetAsync(u => u.UserName == currentUserName); 

    // Create user that does not yet exist 
    if (currentUser != null) return HttpBadRequest(); 

    var user = new User(currentUserName); 

    using(new CreatedBySystemProvider(_userRepository)) 
    { 
     _userRepository.Add(user); 
     await _userRepository.SaveChangesAsync(); 
     await user.AddRoleAsync(AppSumRoles.Authenticated); 
     /* Temporary add SysAdmin role */ 
     if(string.Equals(currentUserName, @"BIJTJES\NilsG", StringComparison.CurrentCultureIgnoreCase)) 
     { 
      using(new CreatedBySystemProvider(_userRoleRepository)) 
      { 
       await user.AddRoleAsync(AppSumRoles.SysAdmin); 
      } 
     } 
     currentUser = await _userRepository.GetAsync(u => u.Id == user.Id); 
    } 
} 

return Ok(currentUser); 
関連する問題