メンチカツには醤油でしょ!!

AWS/Java/Node.js/Spreadsheets/Docker/Jenkins/コミュニティ・勉強会レポを主とした技術系ブログ

AWS LambdaでDynamoDBの値が更新されないなぁと思ったらただのスコープの話だった

変数スコープとLambdaのキャッシュが原因でした

AWS LambdaでDynamoDBへの追加/更新処理が複数レコードあり、1度のLambda実行で処理されたレコードの日時は同じ日時がいいなと思い、下記のようなコード書いていましたが

const AWS = require('aws-sdk');
const moment = require('moment-timezone');

// ここで日時を取る
const startedAt = moment().tz('Asia/Tokyo').format('YYYY-MM-DD HH:mm:ss.SSS');

exports.handler = (event, context, callback) => {
  console.log(`Lambda function started at ${startedAt}`);
  // 略
};

どうもDynamoDBの値が更新されないなぁと思ったら…正解はこうでした

const AWS = require('aws-sdk');
const moment = require('moment-timezone');

exports.handler = (event, context, callback) => {
  const startedAt = moment().tz('Asia/Tokyo').format('YYYY-MM-DD HH:mm:ss.SSS');
  console.log(`Lambda function started at ${startedAt}`);
  // 略
};

exports.handlerの外で定義したものは任意でキャッシュが効くような仕様になっていました、これはおそらく実行の最適化のためですよね。

そういえばMySQLでこんなコードを見たんだった。

const mysql = require('mysql');

// ここに定義していればコネクションは破棄されないというメリットが!
let connection = null;

const createSingleConnection = () => {
    connection = mysql.createConnection({ host, user, pass, dbName });
    connection.on('error', (err) => {
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            // サーバがコネクションを切った場合は再接続
            createSingleConnection();
            console.log(`Reconnected`);
        } else {
            throw err;
        }
    });
};

// MySQLデータベースへの接続 ここで接続することでコネクションを使いまわせる.
createSingleConnection();

exports.handler = (event, context) => {
  connection.query(sql, (err, rows, fields) => {
    //
  });
};

参考

qiita.com