Триггер SQL Azure для функций

Примечание.

В функциях плана потребления автоматическое масштабирование не поддерживается для триггера SQL. Если автоматический процесс масштабирования останавливает функцию, все события будут остановлены, и его потребуется перезапустить вручную.

Используйте премиум или выделенные планы для масштабирования преимуществ с помощью триггера SQL.

Триггер SQL Azure использует функции отслеживания изменений SQL для мониторинга таблицы SQL для изменений и активации функции при создании, обновлении или удалении строки. Сведения о конфигурации отслеживания изменений для использования с триггером SQL Azure см. в разделе "Настройка отслеживания изменений". Сведения о настройке расширения SQL Azure для Функции Azure см. в обзоре привязки SQL.

Решения по масштабированию триггеров SQL Azure для планов потребления и уровня "Премиум" выполняются с помощью масштабирования на основе целевого объекта. Дополнительные сведения см. в статье о масштабировании на основе целевого объекта.

Общие сведения о функциях

Привязка триггера SQL Azure использует цикл опроса для проверки изменений, запуская пользовательную функцию при обнаружении изменений. На высоком уровне цикл выглядит следующим образом:

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

Изменения обрабатываются в том порядке, в который были внесены их изменения, при первом обработке старейших изменений. Несколько заметок об обработке изменений:

  1. Если изменения в нескольких строках выполняются сразу, то точный порядок их отправки в функцию основан на порядке, возвращаемом функцией CHANGETABLE.
  2. Изменения объединяются вместе для строки. Если несколько изменений вносятся в строку между каждой итерацией цикла, то для этой строки существует только одна запись изменений, которая будет отображать разницу между последним обработанным состоянием и текущим состоянием.
  3. Если изменения внесены в набор строк, а затем еще один набор изменений вносятся в половину этих же строк, то половина строк, которые не были изменены во второй раз, обрабатываются сначала. Эта логика обработки связана с приведенным выше примечанием с пакетными изменениями. Триггер увидит только последнее изменение, внесенное и используемое для порядка их обработки.

Дополнительные сведения об отслеживании изменений и его использовании приложениями, такими как триггеры SQL Azure, см. в статье о работе с отслеживанием изменений.

Пример использования

Дополнительные примеры триггера SQL Azure доступны в репозитории GitHub.

Пример ссылается на ToDoItem класс и соответствующую таблицу базы данных:

namespace AzureSQL.ToDo
{
    public class ToDoItem
    {
        public Guid Id { get; set; }
        public int? order { get; set; }
        public string title { get; set; }
        public string url { get; set; }
        public bool? completed { get; set; }
    }
}
CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

Отслеживание изменений включено в базе данных и в таблице:

ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);

ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;

Триггер SQL привязывается к IReadOnlyList<SqlChange<T>>списку SqlChange объектов с двумя свойствами:

  • Элемент: измененный элемент. Тип элемента должен соответствовать схеме таблицы, как показано в ToDoItem классе.
  • Операция: значение из SqlChangeOperation перечисления. Возможные значения: Insert, Update и Delete.

В следующем примере показана функция C#, вызываемая при изменении ToDo таблицы:

using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Sql;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;


namespace AzureSQL.ToDo
{
    public static class ToDoTrigger
    {
        [Function("ToDoTrigger")]
        public static void Run(
            [SqlTrigger("[dbo].[ToDo]", "SqlConnectionString")]
            IReadOnlyList<SqlChange<ToDoItem>> changes,
            FunctionContext context)
        {
            var logger = context.GetLogger("ToDoTrigger");
            foreach (SqlChange<ToDoItem> change in changes)
            {
                ToDoItem toDoItem = change.Item;
                logger.LogInformation($"Change operation: {change.Operation}");
                logger.LogInformation($"Id: {toDoItem.Id}, Title: {toDoItem.title}, Url: {toDoItem.url}, Completed: {toDoItem.completed}");
            }
        }
    }
}

Пример использования

Дополнительные примеры триггера SQL Azure доступны в репозитории GitHub.

Пример ссылается на ToDoItem класс, класс, SqlChangeToDoItem SqlChangeOperation перечисление и соответствующую таблицу базы данных:

В отдельном файле ToDoItem.java:

package com.function;
import java.util.UUID;

public class ToDoItem {
    public UUID Id;
    public int order;
    public String title;
    public String url;
    public boolean completed;

    public ToDoItem() {
    }

    public ToDoItem(UUID Id, int order, String title, String url, boolean completed) {
        this.Id = Id;
        this.order = order;
        this.title = title;
        this.url = url;
        this.completed = completed;
    }
}

В отдельном файле SqlChangeToDoItem.java:

package com.function;

public class SqlChangeToDoItem {
    public ToDoItem item;
    public SqlChangeOperation operation;

    public SqlChangeToDoItem() {
    }

    public SqlChangeToDoItem(ToDoItem Item, SqlChangeOperation Operation) {
        this.Item = Item;
        this.Operation = Operation;
    }
}

В отдельном файле SqlChangeOperation.java:

package com.function;

import com.google.gson.annotations.SerializedName;

public enum SqlChangeOperation {
    @SerializedName("0")
    Insert,
    @SerializedName("1")
    Update,
    @SerializedName("2")
    Delete;
}
CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

Отслеживание изменений включено в базе данных и в таблице:

ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);

ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;

Триггер SQL привязывается к SqlChangeToDoItem[]массиву объектов с двумя SqlChangeToDoItem свойствами:

  • элемент: измененный элемент. Тип элемента должен соответствовать схеме таблицы, как показано в ToDoItem классе.
  • операция: значение из SqlChangeOperation перечисления. Возможные значения: Insert, Update и Delete.

В следующем примере показана функция Java, вызываемая при изменении ToDo таблицы:

package com.function;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.sql.annotation.SQLTrigger;
import com.function.Common.SqlChangeToDoItem;
import com.google.gson.Gson;

import java.util.logging.Level;

public class ProductsTrigger {
    @FunctionName("ToDoTrigger")
    public void run(
            @SQLTrigger(
                name = "todoItems",
                tableName = "[dbo].[ToDo]",
                connectionStringSetting = "SqlConnectionString")
                SqlChangeToDoItem[] todoItems,
            ExecutionContext context) {

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

Пример использования

Дополнительные примеры триггера SQL Azure доступны в репозитории GitHub.

Пример ссылается на таблицу ToDoItem базы данных:

CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

Отслеживание изменений включено в базе данных и в таблице:

ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);

ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;

Триггер SQL привязывается к todoChangesсписку объектов с двумя свойствами:

  • элемент: измененный элемент. Структура элемента будет соответствовать схеме таблицы.
  • операция: возможные значения: Insertи UpdateDelete.

В следующем примере показана функция PowerShell, вызываемая при изменении ToDo таблицы.

Ниже приведены данные привязки в файле function.json:

{
    "name": "todoChanges",
    "type": "sqlTrigger",
    "direction": "in",
    "tableName": "dbo.ToDo",
    "connectionStringSetting": "SqlConnectionString"
}

В разделе Конфигурация описываются эти свойства.

Ниже приведен пример кода PowerShell для функции в run.ps1 файле:

using namespace System.Net

param($todoChanges)
# 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 = $todoChanges | ConvertTo-Json -Compress
Write-Host "SQL Changes: $changesJson"

Пример использования

Дополнительные примеры триггера SQL Azure доступны в репозитории GitHub.

Пример ссылается на таблицу ToDoItem базы данных:

CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

Отслеживание изменений включено в базе данных и в таблице:

ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);

ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;

Триггер SQL привязывает todoChangesмассив объектов с двумя свойствами:

  • элемент: измененный элемент. Структура элемента будет соответствовать схеме таблицы.
  • операция: возможные значения: Insertи UpdateDelete.

В следующем примере показана функция JavaScript, вызываемая при изменении ToDo таблицы.

Ниже приведены данные привязки в файле function.json:

{
    "name": "todoChanges",
    "type": "sqlTrigger",
    "direction": "in",
    "tableName": "dbo.ToDo",
    "connectionStringSetting": "SqlConnectionString"
}

В разделе Конфигурация описываются эти свойства.

Ниже приведен пример кода JavaScript для функции в index.js файле:

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

Пример использования

Дополнительные примеры триггера SQL Azure доступны в репозитории GitHub.

Пример ссылается на таблицу ToDoItem базы данных:

CREATE TABLE dbo.ToDo (
    [Id] UNIQUEIDENTIFIER PRIMARY KEY,
    [order] INT NULL,
    [title] NVARCHAR(200) NOT NULL,
    [url] NVARCHAR(200) NOT NULL,
    [completed] BIT NOT NULL
);

Отслеживание изменений включено в базе данных и в таблице:

ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);

ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;

Триггер SQL привязывается к переменной todoChanges, списку объектов с двумя свойствами:

  • элемент: измененный элемент. Структура элемента будет соответствовать схеме таблицы.
  • операция: возможные значения: Insertи UpdateDelete.

В следующем примере показана функция Python, вызываемая при изменении ToDo таблицы.

Ниже приведен пример кода Python для файла function_app.py:

import json
import logging
import azure.functions as func
from azure.functions.decorators.core import DataType

app = func.FunctionApp()

@app.function_name(name="ToDoTrigger")
@app.sql_trigger(arg_name="todo",
                        table_name="ToDo",
                        connection_string_setting="SqlConnectionString")
def todo_trigger(todo: str) -> None:
    logging.info("SQL Changes: %s", json.loads(todo))

Атрибуты

Библиотека C# использует атрибут SqlTrigger для объявления триггера SQL в функции, которая имеет следующие свойства:

Свойство атрибута Description
TableName Обязательный. Имя таблицы, отслеживаемой триггером.
ConnectionStringSetting Обязательный. Имя параметра приложения, содержащего строка подключения для базы данных, содержащей таблицу, отслеживаемую для изменений. Имя параметра строки подключения соответствует параметру приложения (для local.settings.json локальной разработки), который содержит строку подключения к экземплярам Azure SQL или SQL Server.
LeasesTableName Необязательно. Имя таблицы, используемой для хранения аренды. Если не указано, имя таблицы аренды будет Leases_{FunctionId}_{TableId}. Дополнительные сведения о том, как это создается, можно найти здесь.

Заметки

В библиотеке среды выполнения функций Java используйте заметку @SQLTrigger (com.microsoft.azure.functions.sql.annotation.SQLTrigger) для параметров, значение которых будет поступать из SQL Azure. Эта заметка поддерживает следующие элементы:

Элемент Description
name Необходимые. Имя параметра, к которому привязывается триггер.
tableName Обязательный. Имя таблицы, отслеживаемой триггером.
connectionStringSetting Обязательный. Имя параметра приложения, содержащего строка подключения для базы данных, содержащей таблицу, отслеживаемую для изменений. Имя параметра строки подключения соответствует параметру приложения (для local.settings.json локальной разработки), который содержит строку подключения к экземплярам Azure SQL или SQL Server.
LeasesTableName Необязательно. Имя таблицы, используемой для хранения аренды. Если не указано, имя таблицы аренды будет Leases_{FunctionId}_{TableId}. Дополнительные сведения о том, как это создается, можно найти здесь.

Настройка

В следующей таблице описываются свойства конфигурации привязки, которые задаются в файле function.json.

Свойство в function.json Description
name Необходимые. Имя параметра, к которому привязывается триггер.
type Необходимые. Должен иметь значениеsqlTrigger.
direction Обязательный. Должен иметь значениеin.
tableName Обязательный. Имя таблицы, отслеживаемой триггером.
connectionStringSetting Обязательный. Имя параметра приложения, содержащего строка подключения для базы данных, содержащей таблицу, отслеживаемую для изменений. Имя параметра строки подключения соответствует параметру приложения (для local.settings.json локальной разработки), который содержит строку подключения к экземплярам Azure SQL или SQL Server.
LeasesTableName Необязательно. Имя таблицы, используемой для хранения аренды. Если не указано, имя таблицы аренды будет Leases_{FunctionId}_{TableId}. Дополнительные сведения о том, как это создается, можно найти здесь.

Дополнительные настройки

Следующие необязательные параметры можно настроить для триггера SQL для локальной разработки или для облачных развертываний.

host.json

В этом разделе описываются параметры конфигурации, доступные для этой привязки в версии 2.x или новее. Параметры в файле host.json применяются ко всем функциям в экземпляре приложения-функции. В приведенном ниже примере файла host.json содержатся только параметры этой привязки для версии 2.x или новее. Дополнительные сведения о параметрах конфигурации приложения-функции в версии 2.x или более поздней см. в статье Справочник по файлу host.json для Функций Azure.

Параметр По умолчанию. Description
MaxBatchSize 100 Максимальное количество изменений, обрабатываемых с каждой итерацией цикла триггера перед отправкой в триггерную функцию.
ОпросыIntervalMs 1000 Задержка в миллисекундах между обработкой каждого пакета изменений. (1000 мс составляет 1 секунду)
MaxChangesPerWorker 1000 Верхний предел числа ожидающих изменений в пользовательской таблице, разрешенных для каждой рабочей роли приложения. Если количество изменений превышает это ограничение, это может привести к горизонтальному масштабированию. Параметр применяется только для приложений-функций Azure с включенным масштабированием на основе среды выполнения.

Пример файла host.json

Ниже приведен пример host.json файла с необязательными параметрами:

{
  "version": "2.0",
  "extensions": {
      "Sql": {
        "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 может содержать секреты, например строки подключения, его не следует хранить в удаленном репозитории. Средства, которые поддерживают функции, предоставляют способы синхронизации параметров в файле local.settings.json с помощью параметров приложения в приложении-функции, в котором развернут проект.

Параметр По умолчанию. Description
Sql_Trigger_BatchSize 100 Максимальное количество изменений, обрабатываемых с каждой итерацией цикла триггера перед отправкой в триггерную функцию.
Sql_Trigger_PollingIntervalMs 1000 Задержка в миллисекундах между обработкой каждого пакета изменений. (1000 мс составляет 1 секунду)
Sql_Trigger_MaxChangesPerWorker 1000 Верхний предел числа ожидающих изменений в пользовательской таблице, разрешенных для каждой рабочей роли приложения. Если количество изменений превышает это ограничение, это может привести к горизонтальному масштабированию. Параметр применяется только для приложений-функций Azure с включенным масштабированием на основе среды выполнения.

Пример файла local.settings.json

Ниже приведен пример local.settings.json файла с необязательными параметрами:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "SqlConnectionString": "",
    "Sql_Trigger_MaxBatchSize": 300,
    "Sql_Trigger_PollingIntervalMs": 1000,
    "Sql_Trigger_MaxChangesPerWorker": 100
  }
}

Настройка отслеживания изменений (обязательно)

Настройка отслеживания изменений для использования с триггером SQL Azure требует двух шагов. Эти действия можно выполнить из любого средства SQL, поддерживающего выполнение запросов, включая Visual Studio Code, Azure Data Studio или SQL Server Management Studio.

  1. Включите отслеживание изменений в базе данных SQL, подставив your database name имя базы данных, в которой находится таблица:

    ALTER DATABASE [your database name]
    SET CHANGE_TRACKING = ON
    (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
    

    Параметр CHANGE_RETENTION задает период времени, для которого хранится информация об отслеживании изменений (журнал изменений). Хранение журнала изменений базой данных SQL может повлиять на функциональные возможности триггера. Например, если функция Azure отключена в течение нескольких дней, а затем возобновляется, база данных будет содержать изменения, произошедшие за последние два дня в приведенном выше примере установки.

    Этот AUTO_CLEANUP параметр используется для включения или отключения задачи очистки, которая удаляет старые сведения об отслеживании изменений. Если временная проблема, препятствующая запуску триггера, отключение автоматической очистки может быть полезно для приостановки удаления информации старше срока хранения до устранения проблемы.

    Дополнительные сведения о параметрах отслеживания изменений см. в документации по SQL.

  2. Включите отслеживание изменений в таблице, подставив your table name имя таблицы для отслеживания (при необходимости изменяя схему):

    ALTER TABLE [dbo].[your table name]
    ENABLE CHANGE_TRACKING;
    

    Триггер должен иметь доступ на чтение таблицы, отслеживаемой для изменений и системных таблиц отслеживания изменений. Каждый триггер функции имеет связанную таблицу отслеживания изменений и таблицу аренды в схеме az_func. Эти таблицы создаются триггером, если они еще не существуют. Дополнительные сведения об этих структурах данных см. в документации по библиотеке привязки SQL Azure.

Включение масштабирования на основе среды выполнения

При необходимости функции могут автоматически масштабироваться на основе количества изменений, ожидающих обработки в пользовательской таблице. Чтобы функции могли правильно масштабироваться в плане "Премиум" при использовании триггеров SQL, необходимо включить мониторинг масштабирования среды выполнения.

В портале Azure в приложении-функции выберите Конфигурация и на вкладке Параметры среды выполнения функций установите переключатель Мониторинг масштабирования среды выполнения в положение Вкл.

Снимок экрана: панель портал Azure для включения масштабирования среды выполнения.

Поддержка повторных попыток

Дополнительные сведения о поддержке повторных попыток триггера SQL и таблицах аренды доступны в репозитории GitHub.

Повторные попытки запуска

Если во время запуска возникает исключение, среда выполнения узла автоматически пытается перезапустить прослушиватель триггера с экспоненциальной стратегией обратной отработки. Эти повторные попытки продолжаются до успешного запуска прослушивателя или отмены запуска.

Сбой повторных попыток подключения

Если функция успешно запускается, но ошибка приводит к прерыванию подключения (например, к серверу в автономном режиме), то функция продолжает пытаться повторно открыть подключение, пока функция не будет остановлена или подключение будет выполнено успешно. Если подключение успешно установлено повторно, он выбирает изменения обработки, в которых он остался.

Обратите внимание, что эти повторные попытки находятся вне встроенной логики повтора подключения бездействия, которая может быть настроена с ConnectRetryCount помощью параметров и ConnectRetryInterval строка подключения. В первую очередь выполняется попытка повторного подключения встроенного бездействия и при неудачном подключении привязка триггера пытается повторно установить подключение.

Повторные попытки исключения функций

Если исключение возникает в пользовательской функции при обработке изменений, то пакет строк, которые в настоящее время обрабатываются, повторно извлекаются за 60 секунд. Другие изменения обрабатываются как обычные в течение этого времени, но строки в пакете, вызвавшие исключение, игнорируются до истечения периода ожидания.

Если выполнение функции завершается пять раз в строке для заданной строки, эта строка полностью игнорируется для всех будущих изменений. Так как строки в пакете не детерминированы, строки в неудачном пакете могут оказаться в разных пакетах в последующих вызовах. Это означает, что не все строки в неудачном пакете обязательно будут игнорироваться. Если другие строки в пакете были теми, которые вызывают исключение, "хорошие" строки могут в конечном итоге в другом пакете, который не завершается ошибкой в будущих вызовах.

Следующие шаги