簡體   English   中英

AWS Lambda函數同步問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM