You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda复用MySQL连接导致数据查询缺失问题咨询

AWS Lambda + API Gateway 数据库查询数据缺失问题

问题场景

使用AWS Lambda搭配API Gateway时遇到如下问题:

  • 一个Lambda负责向MySQL数据库插入数据,另一个Lambda负责查询数据列表
  • 初次查询时,新插入的数据会缺失;但再次调用查询Lambda时,所有数据均能正常获取
  • 原本按推荐将数据库连接定义在Lambda handler之外,后续改为每次调用handler时强制关闭连接(即每次调用新建连接),问题得以解决

复现代码(PyMySQL)

def sample_code():
    # Create Connection 1 (//Lambda 1)
    conn_1 = get_connection()
    cursor_1 = get_cursor(conn_1)
    random_string = str(random.randint(1, 100))
    cursor_1.execute(SQL_INSERT, ("John", random_string))
    conn_1.commit()
    print(f"1. Inserted {('John', random_string)}")
    cursor_1.execute(SQL_GET)
    result = cursor_1.fetchall()
    print(f"1. All rows -> {result=}")
    
    # Create a new Connection/Cursor 2 (//Lambda 2)
    conn_2 = get_connection()
    cur_2 = get_cursor(conn_2)
    random_string = str(random.randint(1, 100))
    cur_2.execute(SQL_INSERT, ("Doe", random_string))
    conn_2.commit()
    print(f"2. Inserted {('Doe', random_string)}")
    cur_2.execute(SQL_GET)
    results = cur_2.fetchall()
    cur_2.close()
    conn_2.close()
    print(f"2. All rows -> {results=}")

    # Fetch results using Connection/Cursor 1. (Lambda 1)
    cursor_1.execute(SQL_GET)
    get_resp = cursor_1.fetchall()
    print(f"\n1. All rows {get_resp=}")
    
    # Create a new connection 3 (//Lambda 3)
    con3 = get_connection()
    cur_3 = get_cursor(con3)
    cur_3.execute(SQL_GET)
    results = cur_3.fetchall()
    print(f"\n3. All rows -> {results=}")

输出结果

1. Inserted ('John', '75')
1. All rows -> result=((None, '75', 'John'),)
2. Inserted ('Doe', '66')
2. All rows -> results=((None, '75', 'John'), (None, '66', 'Doe'))

1. All rows get_resp=((None, '75', 'John'),)

3. All rows -> results=((None, '75', 'John'), (None, '66', 'Doe'))

核心疑问

  1. 为何用连接2插入的数据,连接1无法查询到?
  2. 是否必须关闭数据库连接/游标?

问题原因与解答

1. 数据查询不到的根本原因

这是MySQL事务隔离级别与Lambda执行环境复用共同作用的结果:

  • MySQL默认事务隔离级别为REPEATABLE READ(可重复读),该级别下,事务开启后会创建一致性快照,后续查询仅返回快照建立时的数据状态,无法看到其他事务提交的新数据。
  • Lambda的执行环境复用机制:将连接定义在handler之外时,Lambda的暖环境会保留该连接,对应事务长期处于未关闭状态(除非显式提交/回滚并关闭连接)。当连接2插入数据并提交后,连接1的事务仍在使用初始快照,因此查不到新数据。

你的示例代码也验证了这一点:连接1未关闭,后续查询始终使用初始快照;而连接2关闭后,新创建的连接3能获取最新数据,因为新连接会生成全新的一致性快照。

2. 是否必须关闭连接/游标?

并非绝对“必须”,但在Lambda环境下强烈建议每次调用后关闭连接与游标,原因如下:

  • 避免事务快照复用导致的数据不一致问题,即你遇到的场景。
  • Lambda执行环境的复用具有不确定性,长期保留的连接可能因数据库端超时机制被强制断开,导致后续调用出现连接错误。
  • 数据库连接数有限,Lambda并发调用若均保留连接,可能耗尽数据库连接池,导致新请求无法建立连接。

若想优化连接复用,可尝试:

  • 在handler内显式提交事务(即使无修改操作),刷新连接快照,让后续查询获取最新数据。
  • 给连接设置合理超时时间,或每次调用前检查连接有效性,无效则重新建立。

但最稳妥的方式仍是每次调用Lambda后关闭连接与游标,规避环境复用带来的各类问题。


内容的提问来源于stack exchange,提问作者Gokul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:39:32