multithreading - 将并发客户端调用同步到 azure 移动服务

标签 multithreading azure azure-mobile-services simultaneous

我有一个关于同时客户端调用 azure 移动服务功能的基本问题。 如何防止多个客户端/用户同时读取和更新变量和数据库表?

我想使用 AZURE 移动服务构建排行榜,对于客户端/游戏代码,我使用 Marmalade SDK。 我为该服务创建了一个名为“highscore”的数据库表,其中“track_id”是主键。 当我开始测试时,db 表是空的。

在客户端:

我从客户端向我的 AZURE 移动服务发出“HTTP post”调用 该调用包含“TrackId”和“Score”的数据。 我通过依次进行多次调用来模拟多个客户端。

伪代码:

  1. Http1.Post(trackId = 1, trackcore =100) -> "https://game_name.azure-mobile.net/api/test "
  2. Http2.Post(trackId = 1, trackcore =200) -> "https://game_name.azure-mobile.net/api/test "
  3. Http3.Post(trackId = 1, Trackscore =300) -> "https://game_name.azure-mobile.net/api/test "
  4. Http3.Post(trackId = 1, trackcore =400) -> "https://game_name.azure-mobile.net/api/test "

在 AZURE 移动服务代码中:

  exports.post = function(request, response) {
    var mssql = request.service.mssql;
    var trackId = request.param('trackId');
    var trackscore = request.param('trackscore');

    var sql1 = "SELECT * FROM highscore WHERE track_id = '" + trackId + "'";
    mssql.query(sql1, {
      success: function(results) {
        console.log("Length1:" + results.length + ", score:" + trackscore);
        if (results.length == 0) {
          console.log("Create new score" + ", score:" + trackscore);
          var sql2 = "INSERT INTO highscore (track_id, track_score) VALUES ('" + trackId + "','" + trackScore + "')";
          mssql.query(sql2);
        } else if (results.length == 1) {
          console.log("Update score" + ", score:" + trackscore);
          var sql2 = "UPDATE highscore SET track_score = '" + trackScore + "' WHERE track_id = '" + trackId + "'";
          mssql.query(sql2);
        } else {
          console.log('Error. Number of trackId: %s = %d', trackId, results.length);
        }
        mssql.query(sql1, {
          success: function(results) {
            console.log("Length2:" + results.length + ", score:" + trackscore);
          }
        });
      },
      error: function(err) {
        console.log("Error:" + err);
        response.send(statusCodes.OK, {
          message: err
        });
      }
    });
  };

azure 日志:

服务的“LOGS”显示所有客户端调用同时在服务器功能内进行。当某些客户端线程尝试插入已存在的项目时,这会导致出现下面的“错误消息”。

1.  Information     Length2:1, score:400     api/test.js                          Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
2.  Error        {ERROR MESSAGE}           api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
3.  Information  Length2:1, score:400          api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
4.  Information  Length2:1, score:200          api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
5.  Information  Length2:1, score:300          api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
6.  Error        {ERROR MESSAGE}               api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
7.  Information  Update score, score: 200      api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
8.  Information  Length1:1, score: 200         api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
9.  Information  Create new score, score: 100  api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
10. Information  Length1:0, score: 100         api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
11. Information  Create new score, score:400   api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
12. Information  Length1:0, score 400          api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎03 
13. Information  Create new score, score:300   api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎02 
14. Information  Length1:0, score:300          api/test.js                        Thu Jan 29 2015, ‎21‎:‎37‎:‎02 
{ERROR MESSAGE} = "Error occurred executing query: Error: [Microsoft] [SQL Server Native Client 10.0]
                   [SQL Server]Violation of PRIMARY KEY constraint 'PrimaryKey_3e234221-4811-48a7-bc09-2dac9a666d37'.
                   Cannot insert duplicate key in object 'G.Highscore'. The duplicate key value is (1)."

问题

问题在于,不同的调用同时在服务器代码内部进行,从而以不可预测的顺序进行 SQL 查询、更新和读取变量。应该如何处理?

最佳答案

Azure 移动服务实现乐观并发,其方式是不使用“锁”来防止并发问题,而是允许客户端向服务发送更新,但如果另一个客户端有之前更新过相同的项目,那么最后一次更新将失败(并有适当的响应表明这一点)。如果客户端收到这样的“冲突”响应,那么它可以尝试处理冲突(例如,让服务器获胜,用新版本重新发送更新,表明它想要覆盖以前的更新,让用户选择等。 )。

This post谈论服务如何实现乐观并发。 This post展示了如何使用托管客户端 SDK 来使用该功能(在编写该功能时,尚不存在对其他客户端平台的支持,但后来它们已更新)。

关于multithreading - 将并发客户端调用同步到 azure 移动服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28192446/

相关文章:

java - 在新线程中有监听器

python - 如何在 python 中使用 MSAL 获取访问 token 时避免在浏览器中弹出标签

azure - 在 Powershell 中创建 Azure API 管理标签

java - 继承的类不会存储在 Windows Azure 移动服务中

c# - Azure 移动服务 - 自定义 API 在本地运行,但部署到 Azure 时收到 404

c++ - 如何将数据传递给不同的线程

c++ - 这个简单的 C++ 程序是多线程的吗?

java - Java 中的分层互斥锁

Azure 事件中心脱机

Azure 日志显示 : "The supplied notification payload is invalid" for official Xamarin. Android 示例