AWS Lambda DynamoDB putItem 总是执行两次
AWS Lambda DynamoDB putItem executed twice, always
最有可能是愚蠢的问题,但找不到我所看到的 Lambda 行为的明确答案。
我创建了最简单的 Lambda 函数,将虚拟记录放入 DynamoDB table(以同步方式):
const AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
var myTable = 'my-secret-table-name';
var i;
for(i=0; i<10; i++){
var params = {
TableName:myTable,
Item:{
PK: i.toString(),
SK: 'whatever'
}
};
await docClient.put(params, function(err, data) {
if (err) {
console.error("Error inserting to a table ", JSON.stringify(err, null, 2));
} else {
console.log("Insert successfull. Run: "+ i);
}
}).promise();
}
return "Success";
};
它运行完美,所需的记录已插入到 DynamoDB table。但是当我查看 lambda 日志时,我会看到以下内容:
2020-11-18 21:57:06.674 插入成功。 运行: 0
2020-11-18 21:57:06.696 插入成功。 运行: 1
2020-11-18 21:57:06.773 插入成功。 运行: 1
2020-11-18 21:57:06.775 插入成功。 运行: 2
2020-11-18 21:57:06.856 插入成功。 运行: 2
2020-11-18 21:57:06.875 插入成功。 运行: 3
2020-11-18 21:57:06.933 插入成功。 运行: 3
2020-11-18 21:57:06.936 插入成功。 运行: 4
2020-11-18 21:57:07.012 插入成功。 运行: 4
2020-11-18 21:57:07.054 插入成功。 运行: 5
2020-11-18 21:57:07.153 插入成功。 运行: 5
2020-11-18 21:57:07.156 插入成功。 运行:6
2020-11-18 21:57:07.433 插入成功。 运行:6
2020-11-18 21:57:07.513 插入成功。 运行: 7
2020-11-18 21:57:07.567 插入成功。 运行: 7
2020-11-18 21:57:07.594 插入成功。 运行: 8
2020-11-18 21:57:07.645 插入成功。 运行: 8
2020-11-18 21:57:07.693 插入成功。 运行: 9
2020-11-18 21:57:07.747 插入成功。 运行: 9
无论我 运行 这个函数多少次,我总是让每个 `putItem` 执行两次。我知道 lambda 保证 "at-least-once" 处理但它不应该至少有时执行一次而不是总是执行两次吗?
如果 "at-least-once" 处理是原因,那么为什么 "Run 0" 执行一次而所有其他执行两次?
解释将不胜感激。虽然在这个特定情况下执行 `putItem` 并没有太大变化,但在我开发的更复杂的情况下,它开始给我带来一些麻烦,我不知道我应该接受还是我的代码很糟糕。
问候!
它实际上被执行了两次,因为您正在使用多种相互冲突的方式来解决对 DynamoDB 的异步调用:
- 你有一个内联回调函数,一旦执行结果就绪就会执行。
- 您还使用了 promise() 函数
两者都会导致调用的执行。如果您删除 promise()
的调用或回调函数,应该可以解决。
请查看 Getting to know asynchronous JavaScript: Callbacks, Promises and Async/Await 以详细了解不同方法之间的异同。
最有可能是愚蠢的问题,但找不到我所看到的 Lambda 行为的明确答案。
我创建了最简单的 Lambda 函数,将虚拟记录放入 DynamoDB table(以同步方式):
const AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event, context) => {
var myTable = 'my-secret-table-name';
var i;
for(i=0; i<10; i++){
var params = {
TableName:myTable,
Item:{
PK: i.toString(),
SK: 'whatever'
}
};
await docClient.put(params, function(err, data) {
if (err) {
console.error("Error inserting to a table ", JSON.stringify(err, null, 2));
} else {
console.log("Insert successfull. Run: "+ i);
}
}).promise();
}
return "Success";
};
它运行完美,所需的记录已插入到 DynamoDB table。但是当我查看 lambda 日志时,我会看到以下内容:
2020-11-18 21:57:06.674 插入成功。 运行: 0
2020-11-18 21:57:06.696 插入成功。 运行: 1
2020-11-18 21:57:06.773 插入成功。 运行: 1
2020-11-18 21:57:06.775 插入成功。 运行: 2
2020-11-18 21:57:06.856 插入成功。 运行: 2
2020-11-18 21:57:06.875 插入成功。 运行: 3
2020-11-18 21:57:06.933 插入成功。 运行: 3
2020-11-18 21:57:06.936 插入成功。 运行: 4
2020-11-18 21:57:07.012 插入成功。 运行: 4
2020-11-18 21:57:07.054 插入成功。 运行: 5
2020-11-18 21:57:07.153 插入成功。 运行: 5
2020-11-18 21:57:07.156 插入成功。 运行:6
2020-11-18 21:57:07.433 插入成功。 运行:6
2020-11-18 21:57:07.513 插入成功。 运行: 7
2020-11-18 21:57:07.567 插入成功。 运行: 7
2020-11-18 21:57:07.594 插入成功。 运行: 8
2020-11-18 21:57:07.645 插入成功。 运行: 8
2020-11-18 21:57:07.693 插入成功。 运行: 9
2020-11-18 21:57:07.747 插入成功。 运行: 9
无论我 运行 这个函数多少次,我总是让每个 `putItem` 执行两次。我知道 lambda 保证 "at-least-once" 处理但它不应该至少有时执行一次而不是总是执行两次吗?
如果 "at-least-once" 处理是原因,那么为什么 "Run 0" 执行一次而所有其他执行两次?
解释将不胜感激。虽然在这个特定情况下执行 `putItem` 并没有太大变化,但在我开发的更复杂的情况下,它开始给我带来一些麻烦,我不知道我应该接受还是我的代码很糟糕。
问候!
它实际上被执行了两次,因为您正在使用多种相互冲突的方式来解决对 DynamoDB 的异步调用:
- 你有一个内联回调函数,一旦执行结果就绪就会执行。
- 您还使用了 promise() 函数
两者都会导致调用的执行。如果您删除 promise()
的调用或回调函数,应该可以解决。
请查看 Getting to know asynchronous JavaScript: Callbacks, Promises and Async/Await 以详细了解不同方法之间的异同。