【发布时间】:2022-08-21 08:18:50
【问题描述】:
我正在使用大量并发更新请求测试 DynamoDB,但我有一些疑问。
例如: 在一个金融交易系统中,我有一个名为 Account 的表和一个名为 Transactions 的表。
Accounts:
id: string
balance: Number
Transactions
id: Number
amount: Number
balanceAfter: Number
accountId: string
因此,在执行借记交易时,我会更新 Account 表中的余额,并在交易后使用账户余额创建交易。
如果帐户的余额为 100,我同时执行两个 50 的事务,则帐户余额将为 50 而不是 0,并且数据库中有两个事务,余额为 50。
-
如何锁定 DynamoDB 项目以进行并发更新以避免双重支出? (类似于关系数据库中的 TRANSACTION)
-
运行 UPDATE 后从 DynamoDB 获取更新项目的最安全方法是什么?
编码:
<?php require \'./vendor/autoload.php\'; use Aws\\DynamoDb\\DynamoDbClient; use Aws\\Credentials\\CredentialProvider; function executeDebitTransaction($accountId, $transactionAmount) { $provider = CredentialProvider::defaultProvider(); $client = DynamoDbClient::factory(array( \'version\' => \'2012-08-10\', \'credentials\' => $provider, \'region\' => \'sa-east-1\' )); $response = $client->getItem(array( \'TableName\' => \'Accounts\', \'Key\' => array( \'id\' => array( \'S\' => $accountId )) ) ); $currentBalance = $response[\'Item\'][\'balance\'][\'N\']; $newbalance = (string)((int)$currentBalance - (int)$transactionAmount); $response = $client->updateItem(array( \'TableName\' => \'accounts\', \'Key\' => array( \'id\' => array( \'S\' => $accountId ) ), \'ExpressionAttributeValues\' => array ( \':amount\' => array(\'N\' => $transactionAmount), ), \'UpdateExpression\' => \'SET balance = balance - :amount\' )); // Generate random ID $id = (string)(random_int(1, 1000000000)); $client->putItem(array( \'TableName\' => \'Transactions\', \'Item\' => array( \'id\' => array(\'N\' => $id), \'amount\' => array(\'N\' => $transactionAmount), \'balanceAter\' => array(\'N\' => $newbalance), \'accountId\' => $transactionAmount ) )); } $accountId = \'A1469CCD-10B8-4D31-83A2-86B71BF39EA8\'; $debitAmount = \'50\'; executeDebitTransaction($accountId, $debitAmount);以很少的并发运行此脚本可以完美运行,但是当我增加并行度时,我开始遇到问题。
-
调用 putItem 时指明 ReturnValues,例如UPDATED_NEW 获取更新属性的值。
标签: php amazon-web-services amazon-dynamodb