当前位置: 首页 > 知识库问答 >
问题:

AWS Lambda函数同步问题

松铭
2023-03-14

我有一个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库还是来自我自己的代码

共有1个答案

宇文念
2023-03-14

好吧,经过几个小时的绞尽脑汁,我终于明白了。最终引导我走上正确道路的答案可以在这里找到

如果有人在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));
 }



 类似资料:
  • 问题内容: 首先,这是一个非常特殊的情况,它以错误的方式故意将异步调用改型为一个非常同步的代码库,该代码库长成千上万行,并且当前时间不具备进行更改的能力。对的。” 它伤害了我的每一个生命,但是现实和理想往往并没有相互融合。我知道这很糟糕。 好的,顺便说一句,我该如何做,这样我可以: 示例(或缺少示例)全部使用库和/或编译器,这两种库均不适用于此解决方案。我需要一个如何使其冻结的具体示例(例如,在调

  • 本文向大家介绍不同js异步函数同步的实现方法,包括了不同js异步函数同步的实现方法的使用技巧和注意事项,需要的朋友参考一下 不同函数达到同步的函数模拟 funcList是函数执行函数的队列,其中回调函数中flag=true是同步标记量 以上这篇不同js异步函数同步的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。

  • 问题内容: 我面临pthread的同步问题。threadWaitFunction1,是线程等待函数。我希望行号。仅在243-246完成后才执行247 。但我感到奇怪的是,有时它会在243-246完成之前直接跳到247。 请帮我。 提前致谢。 创建并调用上述线程的线程是: 如果我使用pthread_mutex_lock保护整个函数,但仍然存在相同的问题。 如何确保有序执行?有人可以帮忙吗? 编辑:n

  • 问题内容: 某个地方的人告诉我Java构造函数是同步的,因此在构造过程中不能同时访问它,而我在想:是否有构造函数将对象存储在映射中,而另一个线程在构造之前从该映射检索它完成后,该线程是否会阻塞,直到构造函数完成? 让我用一些代码演示: 假设put / get是地图上唯一的操作,因此我不会通过迭代之类的方法来获取CME,并尝试在此忽略其他明显的缺陷。 我想知道的是,如果另一个线程(显然不是构造该对象

  • 我是消防队的新手。我在用firebase数据库。其中我有两个节点,一个有用户信息,第二个有来自用户的所有评论。这些是数据库结构 用户节点 我要做的是获取一篇文章的所有评论,然后从评论节点获取,这实际上是对文章发表评论的用户键,然后从Firebase获取特定的用户信息。我写了以下代码。 null 评论1用户a 评论2用户b

  • 我在Java写程序,有点担心同步。 这个场景非常“简单”,我们有一个简单的银行账户类,多人可以从账户中取款(虽然他们不能存款),他们也可以检查账户余额。问题是,余额一直在变化,因此我们希望客户查看正确的余额! 到目前为止,这是我的班级。 正如您可以看到的,通过这个实现,我可以确保有人可以从一个account对象获得资金,但是这个account对象被阻止了,然后一个解决方案出现了 添加这似乎解决了我