将同时客户端呼叫同步到azure移动服务

时间:2015-01-28 12:37:14

标签: multithreading azure azure-mobile-services simultaneous

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

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

在客户端:

从客户端我制作" HTTP post"拨打我的AZURE移动服务  该呼叫包含" TrackId"的数据。和"得分"。  我通过一个接一个地打几个电话来模拟多个客户端。

伪代码:

  1. Http1.Post(trackId = 1,trackscore = 100) - > " https://game_name.azure-mobile.net/api/test"
  2. Http2.Post(trackId = 1,trackscore = 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,trackscore = 400) - > " https://game_name.azure-mobile.net/api/test"
  5. 在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 LOG:

    " LOGS"对于该服务显示所有客户端调用同时在服务器功能内。这会导致错误消息"错误消息"下面,当某些客户端线程尝试INSERT已存在的项时。

    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查询,更新和读取变量。应如何处理?

1 个答案:

答案 0 :(得分:0)

Azure移动服务以不使用"锁定"防止并发问题,但它允许客户端向服务发送更新,但如果其他客户端之前更新了相同的项目,则上次更新将失败(具有指示的相应响应)。如果客户收到这样的"冲突"响应,然后它可以尝试处理冲突(例如,让服务器获胜,使用新版本重新发送更新,指示它想要覆盖先前的更新,让用户选择等)。

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