次の方法で共有


Azure Functions の Azure Database for MySQL トリガー バインド (プレビュー)

入力バインドと出力バインドはすべてのプランでサポートされていますが、Azure Database for MySQL トリガー バインドは、プレビュー期間中は Dedicated プランと Premium プラン でのみ使用できます。

Azure Database for MySQL トリガー バインドは、ユーザー テーブルの変更 (挿入と更新) を監視し、更新された行データを使用して関数を呼び出します。

Azure Database for MySQL トリガー バインドでは、 az_func_updated_at と列のデータを使用して、ユーザー テーブルの変更を監視します。 そのため、トリガーのサポートを使用する前に、MySQL テーブルの変更追跡を許可するようにテーブル構造を変更する必要があります。 テーブルで変更の追跡を有効にするには、次のクエリを使用します。 たとえば、 Products テーブルで有効にします。

ALTER TABLE Products
ADD az_func_updated_at TIMESTAMP DEFAULT 
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

リースのテーブルには、ユーザー テーブルの主キーに対応するすべての列と、さらに 3 つの列 ( az_func_AttemptCountaz_func_LeaseExpirationTimeaz_func_SyncCompletedTime) が含まれています。 いずれかの主キー列に同じ名前が付いている場合、結果は競合を一覧表示するエラー メッセージになります。 この場合、トリガーを機能させるには、一覧表示されている主キー列の名前を変更する必要があります。

機能の概要

トリガー関数は、起動時に、変更ポーリング ループとリース更新ループという 2 つの独立したループを開始します。 これらのループは、関数が停止するまで継続的に実行されます。

Azure Database for MySQL トリガー バインドでは、ポーリング ループを使用して変更が確認されます。 ポーリング ループは、変更を検出したときにユーザー関数をトリガーします。 大まかに言うと、ループは次の例のようになります。

while (true) {
    1. Get list of changes on table - up to a maximum number controlled by the MySql_Trigger_MaxBatchSize setting
    2. Trigger function with list of changes
    3. Wait for delay controlled by MySql_Trigger_PollingIntervalMs setting
}

変更は、行われた順序で処理されます。 最も古い変更が最初に処理されます。 変更処理については、次の点を考慮してください。

  • 一度に複数の行で変更が行われる場合、関数に送信される正確な順序は、 az_func_updated_at 列と主キー列の昇順に基づいています。
  • 変更は行に対してバッチ処理されます。 ループの各反復の間に行に複数の変更が発生した場合、その行に存在する最新の変更エントリのみが考慮されます。

現在、マネージド ID は、Azure Functions と Azure Database for MySQL の間の接続ではサポートされていません。

使用例

Azure Database for MySQL トリガーのその他のサンプルは、 GitHub リポジトリで入手できます。

次の例は、Product クラスとそれに対応するデータベース テーブルを示しています。

namespace AzureMySqlSamples.Common
{
    public class Product
    {
        public int? ProductId { get; set; }

        public string Name { get; set; }

        public int Cost { get; set; }

        public override bool Equals(object obj)
        {
            if (obj is Product)
            {
                var that = obj as Product;
                return this.ProductId == that.ProductId && this.Name == that.Name && this.Cost == that.Cost;
            }
            return false;
        }
    }
DROP TABLE IF EXISTS Products;

CREATE TABLE Products (
  ProductId int PRIMARY KEY,
  Name varchar(100) NULL,
  Cost int NULL
);

テーブルに 1 つの列を追加することで、データベースで変更の追跡を有効にします。

ALTER TABLE <table name>  
ADD COLUMN az_func_updated_at TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP 
ON UPDATE CURRENT_TIMESTAMP;

Azure Database for MySQL トリガーは、 IReadOnlyList<MySqlChange<T>>にバインドされ、 MySqlChange オブジェクトが一覧表示されます。 各オブジェクトには、次の 2 つのプロパティがあります。

  • Item: 変更された項目。 ToDoItem クラスに示されているように、項目の型はテーブル スキーマに従う必要があります。
  • Operation: MySqlChangeOperation 列挙体の値。 指定できる値は、挿入と更新の両方に Update

次の例は、 テーブルで変更が発生したときに呼び出される Productを示しています。

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.MySql;
using Microsoft.Extensions.Logging;
using AzureMySqlSamples.Common;

namespace AzureMySqlSamples.TriggerBindingSamples
{
        private static readonly Action<ILogger, string, Exception> _loggerMessage = LoggerMessage.Define<string>(LogLevel.Information, eventId: new EventId(0, "INFO"), formatString: "{Message}");

        [Function(nameof(ProductsTrigger))]
        public static void Run(
            [MySqlTrigger("Products", "MySqlConnectionString")]
            IReadOnlyList<MySqlChange<Product>> changes, FunctionContext context)
        {
            ILogger logger = context.GetLogger("ProductsTrigger");
            // The output is used to inspect the trigger binding parameter in test methods.
            foreach (MySqlChange<Product> change in changes)
            {
                Product product = change.Item;
                _loggerMessage(logger, $"Change operation: {change.Operation}", null);
                _loggerMessage(logger, $"Product Id: {product.ProductId}, Name: {product.Name}, Cost: {product.Cost}", null);
            }
        }
}

使用例

Azure Database for MySQL トリガーのその他のサンプルは、 GitHub リポジトリで入手できます。

この例では、 Product クラス、 MySqlChangeProduct クラス、 MySqlChangeOperation 列挙体、および対応するデータベース テーブルを参照しています。

Product.javaという名前の別のファイル内:

package com.function.Common;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Product {
    @JsonProperty("ProductId")
    private int ProductId;
    @JsonProperty("Name")
    private String Name;
    @JsonProperty("Cost")
    private int Cost;

    public Product() {
    }

    public Product(int productId, String name, int cost) {
        ProductId = productId;
        Name = name;
        Cost = cost;
    }
}

MySqlChangeProduct.javaという名前の別のファイル内:

package com.function.Common;

public class MySqlChangeProduct {
    private MySqlChangeOperation Operation;
    private Product Item;

    public MySqlChangeProduct() {
    }

    public MySqlChangeProduct(MySqlChangeOperation operation, Product item) {
        this.Operation = operation;
        this.Item = item;
    }
}

MySqlChangeOperation.javaという名前の別のファイル内:

package com.function.Common;

import com.google.gson.annotations.SerializedName;

public enum MySqlChangeOperation {
    @SerializedName("0")
    Update
}
DROP TABLE IF EXISTS Products;

CREATE TABLE Products (
  ProductId int PRIMARY KEY,
  Name varchar(100) NULL,
  Cost int NULL
);

データベースで変更の追跡を有効にするには、次の列をテーブルに追加します。

ALTER TABLE <table name>  
ADD COLUMN az_func_updated_at TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP 
ON UPDATE CURRENT_TIMESTAMP;

Azure Database for MySQL トリガーは、 MySqlChangeProduct[]にバインドされます。これは、 MySqlChangeProduct オブジェクトの配列です。 各オブジェクトには、次の 2 つのプロパティがあります。

  • item: 変更された項目。 Product クラスに示されているように、項目の型はテーブル スキーマに従う必要があります。
  • operation: MySqlChangeOperation 列挙体の値。 指定できる値は、挿入と更新の両方に Update

次の例は、 Product テーブルで変更が発生したときに呼び出される Java 関数を示しています。

/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for
 * license information.
 */

package com.function;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.mysql.annotation.MySqlTrigger;
import com.function.Common.MySqlChangeProduct;
import com.google.gson.Gson;

import java.util.logging.Level;

public class ProductsTrigger {
    @FunctionName("ProductsTrigger")
    public void run(
            @MySqlTrigger(
                name = "changes",
                tableName = "Products",
                connectionStringSetting = "MySqlConnectionString")
                MySqlChangeProduct[] changes,
            ExecutionContext context) {

        context.getLogger().log(Level.INFO, "MySql Changes: " + new Gson().toJson(changes));
    }
}

使用例

Azure Database for MySQL トリガーのその他のサンプルは、 GitHub リポジトリで入手できます。

この例では、Product データベース テーブルを参照します。

DROP TABLE IF EXISTS Products;

CREATE TABLE Products (
  ProductId int PRIMARY KEY,
  Name varchar(100) NULL,
  Cost int NULL
);

テーブルに 1 つの列を追加することで、データベースで変更の追跡を有効にします。

ALTER TABLE <table name>  
ADD COLUMN az_func_updated_at TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP 
ON UPDATE CURRENT_TIMESTAMP;

Azure Database for MySQL トリガーは、オブジェクトを一覧表示する Productにバインドされます。 各オブジェクトには、次の 2 つのプロパティがあります。

  • item: 変更された項目。 項目の構造はテーブル スキーマに従います。
  • operation: 可能な値は、挿入と更新の両方に Update

次の例は、 Product テーブルで変更が発生したときに呼び出される PowerShell 関数を示しています。

function.json ファイルのバインド データの例を次に示します。

{
    "bindings": [
      {
        "name": "changes",
        "type": "mysqlTrigger",
        "direction": "in",
        "tableName": "Products",
        "connectionStringSetting": "MySqlConnectionString"
      }
    ],
    "disabled": false
  }

[構成] セクションでは、これらのプロパティについて説明します。

次の例は、run.ps1 ファイル内の関数の PowerShell コードの例です。

using namespace System.Net

param($changes)
# The output is used to inspect the trigger binding parameter in test methods.
# Use -Compress to remove new lines and spaces for testing purposes.
$changesJson = $changes | ConvertTo-Json -Compress
Write-Host "MySql Changes: $changesJson"

使用例

Azure Database for MySQL トリガーのその他のサンプルは、 GitHub リポジトリで入手できます。

この例では、Product データベース テーブルを参照します。

DROP TABLE IF EXISTS Products;

CREATE TABLE Products (
  ProductId int PRIMARY KEY,
  Name varchar(100) NULL,
  Cost int NULL
);

テーブルに 1 つの列を追加することで、データベースで変更の追跡を有効にします。

ALTER TABLE <table name>  
ADD COLUMN az_func_updated_at TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP 
ON UPDATE CURRENT_TIMESTAMP;

Azure Database for MySQL トリガーは、オブジェクトの配列である Changesにバインドされます。 各オブジェクトには、次の 2 つのプロパティがあります。

  • item: 変更された項目。 項目の構造はテーブル スキーマに従います。
  • operation: 可能な値は、挿入と更新の両方に Update

次の例は、 Product テーブルで変更が発生したときに呼び出される JavaScript 関数を示しています。

function.json ファイルのバインド データの例を次に示します。

{
    "bindings": [
      {
        "name": "changes",
        "type": "mysqlTrigger",
        "direction": "in",
        "tableName": "Products",
        "connectionStringSetting": "MySqlConnectionString",
      }
    ],
    "disabled": false
  }

[構成] セクションでは、これらのプロパティについて説明します。

次の例は、 index.js ファイル内の関数の JavaScript コードの例です。

module.exports = async function (context, changes) {
    context.log(`MySql Changes: ${JSON.stringify(changes)}`)
}

使用例

Azure Database for MySQL トリガーのその他のサンプルは、 GitHub リポジトリで入手できます。

この例では、Product データベース テーブルを参照します。

DROP TABLE IF EXISTS Products;

CREATE TABLE Products (
  ProductId int PRIMARY KEY,
  Name varchar(100) NULL,
  Cost int NULL
);

テーブルに 1 つの列を追加することで、データベースで変更の追跡を有効にします。

ALTER TABLE <table name>  
ADD COLUMN az_func_updated_at TIMESTAMP 
DEFAULT CURRENT_TIMESTAMP 
ON UPDATE CURRENT_TIMESTAMP;

Azure Functions バージョン 1.22.0b4 for Python を使用する必要があります。

Azure Database for MySQL トリガーは、オブジェクトを一覧表示する Product という名前の変数にバインドされます。 各オブジェクトには、次の 2 つのプロパティがあります。

  • item: 変更された項目。 項目の構造はテーブル スキーマに従います。
  • operation: 可能な値は、挿入と更新の両方に Update

次の例は、 Product テーブルで変更が発生したときに呼び出される Python 関数を示しています。

次の例は、function_app.py ファイルのサンプル Python コードです。

import json
import logging
import azure.functions as func

app = func.FunctionApp()

# The function is triggered when a change (insert, update)
# is made to the Products table.
@app.function_name(name="ProductsTrigger")
@app.mysql_trigger(arg_name="products",
table_name="Products",
connection_string_setting="MySqlConnectionString")

def products_trigger(products: str) -> None:
logging.info("MySQL Changes: %s", json.loads(products))

属性

属性のプロパティ 説明
TableName 必須。 トリガーが監視するテーブルの名前。
ConnectionStringSetting 必須。 変更を監視するテーブルを含むデータベースの接続文字列を含むアプリ設定の名前。 接続文字列設定の名前は、Azure Database for MySQL への 接続文字列 を含むアプリケーション設定 (ローカル開発用の local.settings.json) に対応します。
LeasesTableName 省略可能。 リースを格納するためのテーブルの名前。 指定されていない場合、名前は Leases_{FunctionId}_{TableId}

注釈

Java 関数ランタイム ライブラリで、値が Azure Database for MySQL から取得されるパラメーターに対して@MySQLTrigger注釈を使用します。 この注釈は、次の要素をサポートします。

要素 説明
name 必須。 トリガーのバインド先パラメーターの名前。
tableName 必須。 トリガーが監視するテーブルの名前。
connectionStringSetting 必須。 変更を監視するテーブルを含むデータベースの接続文字列を含むアプリ設定の名前。 接続文字列設定の名前は、Azure Database for MySQL への 接続文字列 を含むアプリケーション設定 (ローカル開発用の local.settings.json) に対応します。
LeasesTableName 省略可能。 リースを格納するためのテーブルの名前。 指定されていない場合、名前は Leases_{FunctionId}_{TableId}

構成

次の表では、function.json ファイルで設定するバインド構成プロパティについて説明します。

プロパティ 説明
name 必須。 トリガーのバインド先パラメーターの名前。
type 必須。 MysqlTrigger に設定する必要があります。
direction 必須。 in に設定する必要があります。
tableName 必須。 トリガーが監視するテーブルの名前。
connectionStringSetting 必須。 変更を監視するテーブルを含むデータベースの接続文字列を含むアプリ設定の名前。 接続文字列設定の名前は、Azure Database for MySQL への 接続文字列 を含むアプリケーション設定 (ローカル開発用の local.settings.json) に対応します。
LeasesTableName 省略可能。 リースを格納するためのテーブルの名前。 指定されていない場合、名前は Leases_{FunctionId}_{TableId}

オプションの構成

ローカル開発またはクラウド デプロイ用の Azure Database for MySQL トリガーに対して、次のオプション設定を構成できます。

host.json

このセクションでは、バージョン 2.x 以降でこのバインドに使用できる構成設定について説明します。 host.json ファイルの設定は、関数アプリ インスタンスのすべての関数に適用されます。 関数アプリの構成設定の詳細については、 Azure Functions のhost.json リファレンスを参照してください。

設定 既定値 説明
MaxBatchSize 100 トリガーされた関数に送信される前に、トリガー ループの各イテレーションで処理された変更の最大数。
PollingIntervalMs 1000 変更の各バッチを処理するまでの遅延 (ミリ秒単位)。 (1,000 ミリ秒は 1 秒です。
MaxChangesPerWorker 1000 アプリケーション ワーカーごとに許可されるユーザー テーブルの保留中の変更の数の上限。 変更の数がこの制限を超えると、スケールアウトが発生する可能性があります。この設定は、 ランタイム駆動型スケーリングが有効になっている Azure 関数アプリにのみ適用されます。

host.json ファイルの例

オプションの設定を含むファイルhost.json例を次に示します。

{
  "version": "2.0",
  "extensions": {
      "MySql": {
        "MaxBatchSize": 300,
        "PollingIntervalMs": 1000,
        "MaxChangesPerWorker": 100
      }
  },
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    },
    "logLevel": {
      "default": "Trace"
    }
  }
}

local.setting.json

local.settings.json ファイルには、ローカル開発ツールで使用されるアプリの設定と設定が格納されます。 local.settings.json ファイル内の設定は、プロジェクトをローカルで実行している場合にのみ使用されます。 プロジェクトを Azure に発行するときは、関数アプリのアプリ設定にも必要な設定を必ず追加してください。

重要

local.settings.json ファイルには接続文字列などのシークレットが含まれている可能性があるため、リモート リポジトリに格納しないでください。 Azure Functions をサポートするツールを使用すると、local.settings.json ファイルの設定を、プロジェクトのデプロイ先の関数 アプリのアプリ設定 と同期できます。

設定 既定値 説明
MySql_Trigger_BatchSize 100 トリガーされた関数に送信される前に、トリガー ループの各イテレーションで処理された変更の最大数。
MySql_Trigger_PollingIntervalMs 1000 変更の各バッチを処理するまでの遅延 (ミリ秒単位)。 (1,000 ミリ秒は 1 秒です。
MySql_Trigger_MaxChangesPerWorker 1000 アプリケーション ワーカーごとに許可されるユーザー テーブルの保留中の変更の数の上限。 変更の数がこの制限を超えると、スケールアウトが発生する可能性があります。この設定は、 ランタイム駆動型スケーリングが有効になっている Azure 関数アプリにのみ適用されます。

local.settings.json ファイルの例

省略可能な設定を含むlocal.settings.json ファイルの例を次に示します。

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "MySqlConnectionString": "",
    "MySql_Trigger_MaxBatchSize": 300,
    "MySql_Trigger_PollingIntervalMs": 1000,
    "MySql_Trigger_MaxChangesPerWorker": 100
  }
}

変更の追跡を設定する (必須)

Azure Database for MySQL トリガーで使用する変更追跡を設定するには、関数を使用してテーブルに列を追加する必要があります。 これらの手順は、 Visual Studio CodeAzure Data Studio など、クエリの実行をサポートする任意の MySQL ツールから実行できます。

Azure Database for MySQL トリガー バインドでは、 az_func_updated_at と列のデータを使用して、ユーザー テーブルの変更を監視します。 そのため、トリガーのサポートを使用する前に、MySQL テーブルの変更追跡を許可するようにテーブル構造を変更する必要があります。 テーブルで変更の追跡を有効にするには、次のクエリを使用します。 たとえば、 Products テーブルで有効にします。

ALTER TABLE Products;
ADD az_func_updated_at 
TIMESTAMP DEFAULT CURRENT_TIMESTAMP 
ON UPDATE CURRENT_TIMESTAMP;

リースのテーブルには、ユーザー テーブルの主キーに対応するすべての列と、さらに 2 つの列 ( az_func_AttemptCountaz_func_LeaseExpirationTime) が含まれます。 いずれかの主キー列に同じ名前が付いている場合、結果は競合を一覧表示するエラー メッセージになります。 この場合、トリガーを機能させるには、一覧表示されている主キー列の名前を変更する必要があります。

ランタイム駆動型スケーリングを有効にする

必要に応じて、関数は、ユーザー テーブルで処理される保留中の変更の数に基づいて自動的にスケーリングできます。 Azure Database for MySQL トリガーを使用しているときに、Premium プランで関数を適切にスケーリングできるようにするには、ランタイム スケールの監視を有効にする必要があります。

  1. Azure portal の関数アプリで、[ 構成] を選択します。

  2. [ 関数ランタイム設定 ] タブの [ ランタイム スケール監視] で、[オン] を選択します。

    ランタイム スケーリングを有効にするための Azure portal 領域のスクリーンショット。

再試行のサポート

スタートアップの再試行

起動時に例外が発生した場合、ホスト ランタイムは、指数バックオフ戦略を使用してトリガー リスナーの再起動を自動的に試みます。 これらの再試行は、リスナーが正常に開始されるか、スタートアップが取り消されるまで続行します。

関数の例外の再試行

変更処理中にユーザー関数で例外が発生した場合、現在処理中の行のバッチは 60 秒で再試行されます。 その他の変更は、この期間中は通常どおりに処理されますが、タイムアウト期間が経過するまで、例外の原因となったバッチ内の行は無視されます。

特定の行に対して関数の実行が 5 回連続して失敗した場合、その行は今後のすべての変更で無視されます。 バッチ内の行は決定論的ではないので、失敗したバッチ内の行は、後続の呼び出しで異なるバッチになる可能性があります。 この動作は、失敗したバッチ内のすべての行が必ずしも無視されるわけではないことを意味します。 バッチ内の他の行が例外の原因となった場合、"適切な" 行が、将来の呼び出しで失敗しない別のバッチになる可能性があります。