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