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

AWS Lambda连接RDS报错:Cannot enqueue Handshake重复入队

解决MySQL连接在Lambda中首次成功后续报错的问题

这个错误Cannot enqueue Handshake after already enqueuing a Handshake的根源很明确:你把connection实例定义在了Lambda handler的外面,属于全局变量。Lambda的执行环境会被复用——第一次调用时连接成功建立,但后续请求复用同一个容器时,这个连接已经处于握手完成或者已经失效的状态,你再调用connection.connect()就会触发这个错误,因为同一个连接实例不能重复发起握手请求。

下面给你两种可行的解决方案,同时修正你代码里的SQL注入风险:

方案一:每次请求创建新连接

在handler内部创建连接,请求处理完成后关闭连接,这样就不会因为容器复用导致连接状态异常:

var mysql = require('mysql');

exports.handler = async (event) => {
  // 每次请求都创建新的连接实例
  const connection = mysql.createConnection({
    host: "-",
    user: "-",
    password: "-",
    database: "-"
  });

  try {
    const data = await new Promise((resolve, reject) => {
      connection.connect(function(err) {
        if (err) {
          reject(err);
          return;
        }
        // 用占位符替代直接拼接变量,避免SQL注入!
        const sql = `INSERT INTO forms VALUES(?,2,3,4,5,6,7,8,9,10,11);`;
        connection.query(sql, [Math.random() * 10000], function(err, result) {
          // 无论成功失败,都要关闭连接释放资源
          connection.end();
          if (err) {
            console.log("Error->" + err);
            reject(err);
          } else {
            resolve(result);
          }
        });
      });
    });

    return {
      statusCode: 200,
      body: JSON.stringify(data)
    };
  } catch (err) {
    // 出错时也要确保连接关闭
    connection.end();
    return {
      statusCode: 500,
      body: JSON.stringify({ error: err.message })
    };
  }
};

方案二:使用连接池(推荐,性能更优)

连接池会自动管理连接的创建、复用和销毁,既能避免重复创建连接的开销,又能处理连接状态的问题,适合Lambda场景:

var mysql = require('mysql');

// 全局创建连接池(容器复用时可以复用整个池,不用重新初始化)
const pool = mysql.createPool({
  host: "-",
  user: "-",
  password: "-",
  database: "-",
  connectionLimit: 10 // 根据你的请求量调整连接数上限
});

exports.handler = async (event) => {
  try {
    const data = await new Promise((resolve, reject) => {
      // 从连接池中获取可用连接
      pool.getConnection(function(err, connection) {
        if (err) {
          reject(err);
          return;
        }
        // 同样使用占位符防止SQL注入
        const sql = `INSERT INTO forms VALUES(?,2,3,4,5,6,7,8,9,10,11);`;
        connection.query(sql, [Math.random() * 10000], function(err, result) {
          // 将连接放回池中,供后续请求复用
          connection.release();
          if (err) {
            console.log("Error->" + err);
            reject(err);
          } else {
            resolve(result);
          }
        });
      });
    });

    return {
      statusCode: 200,
      body: JSON.stringify(data)
    };
  } catch (err) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error: err.message })
    };
  }
};

额外注意事项

  • SQL注入风险:你的原始代码直接把Math.random()*10000拼到SQL语句里,这是非常危险的做法,一定要用占位符?配合参数数组传递变量,上面的代码已经帮你修正了这一点。
  • 资源释放:无论请求成功还是失败,都要确保连接被关闭(方案一)或者放回池(方案二),避免资源泄漏导致的其他问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:53