Amazon web services 我应该如何处理DynamoDB中碰撞的可能性?

Amazon web services 我应该如何处理DynamoDB中碰撞的可能性?,amazon-web-services,amazon-dynamodb,Amazon Web Services,Amazon Dynamodb,你和我都想去听音乐会,但只剩下一张票了。我们都试图同时预订那张票。使用AWS SDK for PHP的PHP脚本运行以下updateItem API调用,尝试将“票证”的“状态”从0(可用)更改为1(保留) 试试看{ $response=$ddb->updateItem(数组)( “TableName”=>“票证”, “键”=>数组( “tn”=>数组(“N”=>$request[“tn”]) ), “属性更新”=>数组( //设置票证状态(ts)=1。。。 “ts”=>数组( “值”=>数组(

你和我都想去听音乐会,但只剩下一张票了。我们都试图同时预订那张票。使用AWS SDK for PHP的PHP脚本运行以下updateItem API调用,尝试将“票证”的“状态”从0(可用)更改为1(保留)

试试看{
$response=$ddb->updateItem(数组)(
“TableName”=>“票证”,
“键”=>数组(
“tn”=>数组(“N”=>$request[“tn”])
),
“属性更新”=>数组(
//设置票证状态(ts)=1。。。
“ts”=>数组(
“值”=>数组(“N”=>1)
),
),
“预期”=>数组(
“ts”=>数组(
//…其中票证状态(ts)=0
“ComparisonOperator”=>“EQ”,
“AttributeValueList”=>数组(
数组(“N”=>“0”)
)
)
),
“ReturnValues”=>“所有新的”
));
}捕获(例外$e){
$this->ErrorMessage(5,“调用ReserveTicket失败:”。$e->getMessage());
}
理想情况下,DynamoDB将按顺序处理这些问题,我们中第一个通过网络的人将获胜,将状态翻转为1并“拥有”票证,第二个请求失败,因为“预期”状态0将不存在

我正在访问DynamoDB是否可以用于这种类型的用例,或者我是否需要坚持使用良好的关系数据库。这段代码可以工作,但我觉得我不能充分测试它。我的问题是:

  • 对于这个用例,这是正确的方法吗
  • 有没有人看过关于订单请求处理的DynamoDB文档
  • 如果这是一个正确的实现,对测试方案有什么建议吗

  • DynamoDB使用乐观并发控制模式来处理您的用例。它被实现为“条件更新”。 使用条件更新时,仅当读取后属性值未更改时,API才会写入该项。 如果更改了,则会引发错误,由应用程序决定


    详细信息。

    但要做到这一点,请求必须是连续的,对吗?这不考虑同时写入的可能性。那就是我挂断电话的地方。如果updateItem请求同时到达,那么在我的示例中,这两个请求的票证状态都是0。如果没有表锁定,我看不出如何100%解决这个用例。否。该机制设计用于多线程环境。条件写操作在DynamoDB端执行,并且是原子的。“请注意,条件写入是幂等的。这意味着您可以多次发送相同的条件写入请求,但在DynamoDB第一次执行指定的更新后,它不会对项目产生进一步的影响。”这不是超级测试,但是通过在5种不同的设备上使用家庭成员,我成功地进行了一项实验。在服务器上的同一秒(unix秒)内进行了5次调用以保留票证(PHP代码上方)。根据需要,只有一个请求成功,其他4个请求失败。很明显,它确实像广告中所说的那样起作用。我希望在同一秒钟内看到更多的请求(20个就好了)。可能是某种卷曲测试,然后让服务器满负荷运行2秒钟。
            try {
            $response = $ddb->updateItem(array(
                "TableName" => "tickets",
                "Key" => array(
                    "tn" => array("N" => $request["tn"])
                ),
                "AttributeUpdates" => array(
    
                    // set ticket state (ts) = 1...
    
                    "ts" => array(
                        "Value" => array("N" => 1)
                    ),
                    <snip - more fields updated here to "own" the ticket>
                ),
                "Expected" => array(
                    "ts"   => array(
    
                        // ...where ticket state (ts) = 0
    
                        "ComparisonOperator" => "EQ",
                        "AttributeValueList" => array(
                            array( "N" => "0")
                        )
                    )
                ),
                "ReturnValues" => "ALL_NEW"
            ));
    
            } catch (Exception $e) {
                $this->ErrorMessage(5, "Call to ReserveTicket failed: " . $e->getMessage());
            }