[英]AWS Lambda Function Synchronization Issues
我有一個AWS lambda函數,它的工作是偵聽傳入的SNS事件,從Secrets Manager中檢索RDS秘密,並使用npm上的mssql庫執行帶有3個sql查詢的sql事務。
let response;
const mssql = require("mssql");
const AWS = require("aws-sdk");
const uuidv4 = require("uuid/v4");
exports.handler = async (event, context) => {
//console.log(JSON.stringify(event));
var secret;
var snsMessage = JSON.parse(event.Records[0].Sns.Message);
console.log("getting secret");
try {
var data = await new AWS.SecretsManager().getSecretValue({ SecretId: process.env.DATABASE }).promise();
console.log("got data");
if ('SecretString' in data) {
secret = data.SecretString;
secret = JSON.parse(secret);
}
else {
let buff = new Buffer(data.SecretBinary, 'base64');
secret = buff.toString('ascii');
}
const config = {
user: secret.username,
password: secret.password,
server: secret.host,
database: "xxxxx",
options: {
encrypt: true
}
}
console.log("creating config");
try {
//let pool = await mssql.ConnectionPool(config);
let pool = await new mssql.ConnectionPool(config).connect();
console.log("create connection pool");
const transaction = await new mssql.Transaction(pool);
console.log("create transaction");
transaction.begin(async err => {
if (err) console.log("Error" + err);
console.log("getting request object");
var request = await new mssql.Request(transaction);
console.log("have request object");
try {
console.log("Starting request 1");
await request
.input('owner', mssql.UniqueIdentifier, snsMessage.sub)
.input('email', mssql.VarChar(256), snsMessage.email)
.input('phone', mssql.VarChar(256), snsMessage.phone_number)
.input('address', mssql.VarChar(256), snsMessage.address)
.query(`insert into Users
(PK_UUID, EMAIL, PHONE, FIRST_NAME, LAST_NAME, STREET_ADDRESS, CITY, STATE, STATUS, DATE_CREATED)
VALUES
(@owner, @email, @phone, 'Test', 'Test', @address, 'xxx','xx','BASIC', Current_Timestamp)`)
console.log("Request 1 finished");
const newCompanyID = uuidv4();
console.log("Starting request 2");
await request
.input('owner', mssql.UniqueIdentifier, snsMessage.sub)
.input('companyID', mssql.UniqueIdentifier, newCompanyID)
.query(`insert into Company
(PK_UUID, STATUS, DATE_CREATED, OWNER)
VALUES
(@companyID, 'INCOMPLETE', CURRENT_TIMESTAMP, @owner)`)
console.log("request 2 finished");
console.log("starting request 3");
await request
.input('owner', mssql.UniqueIdentifier, snsMessage.sub)
.input('companyID', mssql.UniqueIdentifier, newCompanyID)
.query(`insert into User_Roles
(PK_UUID, USERS, ROLES, COMPANIES, DATE_CREATED)
VALUES
(newid(), @owner,'Company_Owner',@companyID, CURRENT_TIMESTAMP)`)
console.log("Request 3 finished");
console.log("Committing transactions");
await transaction.commit(err => {
if (err) console.log(err);
console.log("transactions committed");
response = {
'statusCode': 200,
'body': JSON.stringify({
message: 'hello world',
})
}
//return err;
return response
})
}
catch (err) {
console.log("error caught 1");
console.log(err);
await transaction.rollback(err => {
if (err) console.log(err);
})
}
})
}
catch (err) {
console.log("error caught 2");
if (err) console.log(err);
}
}
catch (err) {
console.log("error caught 3");
console.log(err);
}
console.log("Down Here")
};
10次中有1次將所有3個查詢正確提交到數據庫。 每隔兩次,console.log消息就會混亂,有時lambda函數會在事務連接打開時終止,從而使連接被阻塞。 這絕對是一個同步問題,但無法確定它是來自AWS Lambda,mssql庫還是來自我自己的代碼。
好吧,經過數小時的猛烈撞擊,我終於明白了。 最終導致我走上正確道路的答案可以在這里找到
萬一其他人在async / await函數內部使用mssql事務來解決這種情況,請參閱下面的通用參考。 基本上,所有查詢都包裝在try / catch塊中。 如果這些查詢中的任何一個失敗,則可以觸發回滾。
const mssql = require('mssql')
const config = {
user: "username",
password: "password",
server: "server",
database: "database-name",
options: {
encrypt: true
}
let pool = await new mssql.ConnectionPool(config).connect();
transaction = await new mssql.Transaction(pool);
await new Promise(resolve => transaction.begin(resolve)); //This is the fix
try{
let request1 = new mssql.Request(transaction);
let result1 = await request1.query('some query');
let request2 = new mssql.Request(transaction);
let result2 = await request2.query('some query');
let request3 = new mssql.Request(transaction);
let result3 = await request3.query('some query');
await new Promise(resolve => transaction.commit(resolve));
}
catch(err)
{
await new Promise(resolve => transaction.rollback(resolve));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.