首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lambda + pg-promise + transaction =随机超时

Lambda + pg-promise + transaction =随机超时
EN

Stack Overflow用户
提问于 2020-05-20 02:42:50
回答 1查看 209关注 0票数 0

在过去的48小时里,我一直在努力解决这个问题,在阅读了大量的答案之后,我在这里,博客,文章,文档等……我还是找不到解决方案!

基本上,我有一个带有2分钟超时的lambda函数。根据日志和洞察,它可以很好地处理大多数请求,但在尝试执行下面的事务时,它会随机失败并出现"timed out“错误。

Lambda代码(为便于阅读而截取):

代码语言:javascript
复制
import pgp from 'pg-promise'
import logger from '../lib/logger'

const Database = pgp()

const db = Database({
 connectionString: process.env.DATABASE_URL,
 max: 3,
 idleTimeoutMillis: 10000,
})

db.connect()
 .then(() => logger.info('Successfully connected to the PG database'))
 .catch(err => logger.error({ err }))

export const handler = async (event, context) => {
 logger.info('transaction start...')

 await db.tx(async tx => {
   await tx.none(
     `
     INSERT INTO...`,
     [someValue1, someValue2]
   )
   const updatedRow = await tx.one(
     `
     UPDATE Something...`,
     [somethingId]
   )
   return someFunction(updatedRow)
 })

 logger.info('transaction end...')
}

const someFunction = async (data) => {
 return db.task('someTask', async ctx => {
   const value = await ctx.oneOrNone(
     `SELECT * FROM Something...`,
     [data.id]
   )

   if (!value) {
     return
   }

   const doStuff = async (points) =>
     ctx.none(
       `UPDATE Something WHERE id =.....`,
       [points]
     )

   // increment points x miles
   if (data.condition1) {
     await doStuff(10)
   }

   if (data.condition2) {
     await doStuff(20)
   }

   if (data.condition3) {
     await doStuff(30)
   }
 })
}

我看到事务开始了,但永远不会结束,所以函数不可避免地会被超时杀死。

我用pg-promise阅读了整个维基,并理解了关于调整、性能、良好实践等的所有内容,但仍然有一些地方是非常错误的。

您可以看到,我还更改了池大小和实验的最大超时,但它没有解决这个问题。

有什么想法吗?

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2020-05-20 03:48:19

最有可能的情况是,您的连接即将耗尽。您没有正确使用它们,同时设置了非常低的3个连接限制。

第一个问题是,您正在通过调用connect来测试连接,而没有使用done进行测试,这将永久占用您的初始/主连接。请参阅the example here,在这里我们在测试连接之后释放它。

第二个问题-在事务内部请求新连接(通过在根db级别调用.task ),这对任何环境都不好,尤其是在可用连接很少的情况下。

任务应该重用当前事务的连接,这意味着您的someFunction应该需要连接上下文,或者至少将其作为可选参数:

代码语言:javascript
复制
const someFunction = async (data, ctx) => {
 return (ctx || db).task('someTask', async tx => {
   const value = await tx.oneOrNone(

您知道,pg-promise中的任务<->事务接口可以完全相互嵌套,将当前连接传播到所有级别。

此外,我建议使用pg-monitor,以获得良好的query+context可视化效果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61898428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档