Gatilho SQL do Azure para Functions

Nota

Nas funções do plano de consumo, o dimensionamento automático não é suportado para o gatilho SQL. Se o processo de dimensionamento automático parar a função, todo o processamento de eventos será interrompido e ele precisará ser reiniciado manualmente.

Use planos premium ou dedicados para dimensionar benefícios com o gatilho SQL.

O gatilho SQL do Azure usa a funcionalidade de controle de alterações SQL para monitorar uma tabela SQL em busca de alterações e acionar uma função quando uma linha é criada, atualizada ou excluída. Para obter detalhes de configuração para controle de alterações para uso com o gatilho SQL do Azure, consulte Configurar o controle de alterações. Para obter informações sobre detalhes de configuração da extensão SQL do Azure para Azure Functions, consulte a visão geral da vinculação SQL.

As decisões de dimensionamento de gatilho do Azure SQL para os planos Consumo e Premium são feitas por meio do dimensionamento baseado em destino. Para obter mais informações, consulte Dimensionamento baseado em destino.

Visão geral da funcionalidade

A associação de gatilho SQL do Azure usa um loop de sondagem para verificar alterações, acionando a função de usuário quando as alterações são detetadas. Em um nível alto, o loop tem esta aparência:

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
}

As alterações são processadas na ordem em que foram feitas, com as alterações mais antigas sendo processadas primeiro. Algumas notas sobre o processamento de alterações:

  1. Se forem feitas alterações em várias linhas de uma só vez, a ordem exata em que elas são enviadas para a função é baseada na ordem retornada pela função CHANGETABLE
  2. As alterações são "agrupadas" em lote para uma linha. Se várias alterações forem feitas em uma linha entre cada iteração do loop, apenas uma única entrada de alteração existirá para essa linha, o que mostrará a diferença entre o último estado processado e o estado atual
  3. Se forem feitas alterações em um conjunto de linhas e, em seguida, outro conjunto de alterações for feito em metade dessas mesmas linhas, a metade das linhas que não foram alteradas uma segunda vez será processada primeiro. Esta lógica de processamento deve-se à nota acima com as alterações sendo agrupadas - o gatilho só verá a "última" alteração feita e usará isso para a ordem em que as processa

Para obter mais informações sobre o controle de alterações e como ele é usado por aplicativos como gatilhos SQL do Azure, consulte Trabalhar com controle de alterações .

Exemplo de utilização

Mais exemplos para o gatilho SQL do Azure estão disponíveis no repositório GitHub.

O exemplo refere-se a uma ToDoItem classe e uma tabela de banco de dados correspondente:

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
);

O controlo de alterações está ativado na base de dados e na tabela:

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

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

O gatilho SQL se liga a um IReadOnlyList<SqlChange<T>>, uma lista de SqlChange objetos cada um com duas propriedades:

  • Item: o item que foi alterado. O tipo do item deve seguir o esquema de tabela como visto na ToDoItem classe.
  • Operação: um valor de SqlChangeOperation enum. Os valores possíveis são Insert, Updatee Delete.

O exemplo a seguir mostra uma função C# que é invocada quando há alterações na ToDo tabela:

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}");
            }
        }
    }
}

Exemplo de utilização

Mais exemplos para o gatilho SQL do Azure estão disponíveis no repositório GitHub.

O exemplo refere-se a uma ToDoItem classe, uma SqlChangeToDoItem classe, um SqlChangeOperation enum e uma tabela de banco de dados correspondente:

Num ficheiro ToDoItem.javaseparado :

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;
    }
}

Num ficheiro SqlChangeToDoItem.javaseparado :

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;
    }
}

Num ficheiro SqlChangeOperation.javaseparado :

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
);

O controlo de alterações está ativado na base de dados e na tabela:

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

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

O gatilho SQL se liga a um SqlChangeToDoItem[], uma matriz de SqlChangeToDoItem objetos cada um com duas propriedades:

  • Item: O item que foi alterado. O tipo do item deve seguir o esquema de tabela como visto na ToDoItem classe.
  • Operação: Um valor de SqlChangeOperation Enum. Os valores possíveis são Insert, Updatee Delete.

O exemplo a seguir mostra uma função Java que é invocada quando há alterações na ToDo tabela:

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));
    }
}

Exemplo de utilização

Mais exemplos para o gatilho SQL do Azure estão disponíveis no repositório GitHub.

O exemplo refere-se a uma ToDoItem tabela de banco de dados:

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
);

O controlo de alterações está ativado na base de dados e na tabela:

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

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

O gatilho SQL se liga a todoChanges, uma lista de objetos cada um com duas propriedades:

  • Item: O item que foi alterado. A estrutura do item seguirá o esquema da tabela.
  • operação: os valores possíveis são Insert, Update, e Delete.

O exemplo a seguir mostra uma função do PowerShell que é invocada quando há alterações na ToDo tabela.

O seguinte é a vinculação de dados no arquivo function.json:

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

A seção de configuração explica essas propriedades.

A seguir está um exemplo de código do PowerShell para a função no run.ps1 arquivo:

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"

Exemplo de utilização

Mais exemplos para o gatilho SQL do Azure estão disponíveis no repositório GitHub.

O exemplo refere-se a uma ToDoItem tabela de banco de dados:

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
);

O controlo de alterações está ativado na base de dados e na tabela:

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

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

O gatilho SQL vincula todoChanges, uma matriz de objetos cada um com duas propriedades:

  • Item: O item que foi alterado. A estrutura do item seguirá o esquema da tabela.
  • operação: os valores possíveis são Insert, Update, e Delete.

O exemplo a seguir mostra uma função JavaScript que é invocada quando há alterações na ToDo tabela.

O seguinte é a vinculação de dados no arquivo function.json:

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

A seção de configuração explica essas propriedades.

A seguir está um exemplo de código JavaScript para a função no index.js arquivo:

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

Exemplo de utilização

Mais exemplos para o gatilho SQL do Azure estão disponíveis no repositório GitHub.

O exemplo refere-se a uma ToDoItem tabela de banco de dados:

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
);

O controlo de alterações está ativado na base de dados e na tabela:

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

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

O gatilho SQL liga-se a uma variável todoChanges, uma lista de objetos cada um com duas propriedades:

  • Item: O item que foi alterado. A estrutura do item seguirá o esquema da tabela.
  • operação: os valores possíveis são Insert, Update, e Delete.

O exemplo a seguir mostra uma função Python que é invocada quando há alterações na ToDo tabela.

A seguir está o código python de exemplo para o arquivo 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))

Atributos

A biblioteca C# usa o atributo SqlTrigger para declarar o gatilho SQL na função, que tem as seguintes propriedades:

Propriedade Attribute Description
TableName Obrigatório. O nome da tabela monitorada pelo gatilho.
ConnectionStringSetting Obrigatório. O nome de uma configuração de aplicativo que contém a cadeia de conexão para o banco de dados que contém a tabela monitorada para alterações. O nome da configuração da cadeia de conexão corresponde à configuração do aplicativo (em local.settings.json para desenvolvimento local) que contém a cadeia de conexão para a instância do SQL ou SQL Server do Azure.
LeasesTableName Opcional. Nome da tabela usada para armazenar locações. Se não for especificado, o nome da tabela de concessões será Leases_{FunctionId}_{TableId}. Mais informações sobre como isso é gerado podem ser encontradas aqui.

Anotações

Na biblioteca de tempo de execução de funções Java, use a @SQLTrigger anotação (com.microsoft.azure.functions.sql.annotation.SQLTrigger) em parâmetros cujo valor viria do SQL do Azure. Esta anotação suporta os seguintes elementos:

Elemento Description
Designação Necessário. O nome do parâmetro ao qual o gatilho se liga.
nome_da_tabela Obrigatório. O nome da tabela monitorada pelo gatilho.
connectionStringSetting Obrigatório. O nome de uma configuração de aplicativo que contém a cadeia de conexão para o banco de dados que contém a tabela monitorada para alterações. O nome da configuração da cadeia de conexão corresponde à configuração do aplicativo (em local.settings.json para desenvolvimento local) que contém a cadeia de conexão para a instância do SQL ou SQL Server do Azure.
LeasesTableName Opcional. Nome da tabela usada para armazenar locações. Se não for especificado, o nome da tabela de concessões será Leases_{FunctionId}_{TableId}. Mais informações sobre como isso é gerado podem ser encontradas aqui.

Configuração

A tabela a seguir explica as propriedades de configuração de vinculação definidas no arquivo function.json.

function.json propriedade Description
Designação Necessário. O nome do parâmetro ao qual o gatilho se liga.
type Necessário. Deve ser definido como sqlTrigger.
direção Obrigatório. Deve ser definido como in.
nome_da_tabela Obrigatório. O nome da tabela monitorada pelo gatilho.
connectionStringSetting Obrigatório. O nome de uma configuração de aplicativo que contém a cadeia de conexão para o banco de dados que contém a tabela monitorada para alterações. O nome da configuração da cadeia de conexão corresponde à configuração do aplicativo (em local.settings.json para desenvolvimento local) que contém a cadeia de conexão para a instância do SQL ou SQL Server do Azure.
LeasesTableName Opcional. Nome da tabela usada para armazenar locações. Se não for especificado, o nome da tabela de concessões será Leases_{FunctionId}_{TableId}. Mais informações sobre como isso é gerado podem ser encontradas aqui.

Configuração Opcional

As seguintes configurações opcionais podem ser definidas para o gatilho SQL para desenvolvimento local ou para implantações em nuvem.

host.json

Esta seção descreve as definições de configuração disponíveis para essa associação nas versões 2.x e superiores. As configurações no arquivo host.json se aplicam a todas as funções em uma instância de aplicativo de função. O exemplo host.json arquivo abaixo contém apenas as configurações da versão 2.x+ para essa ligação. Para obter mais informações sobre definições de configuração de aplicativo de função nas versões 2.x e versões posteriores, consulte host.json referência para o Azure Functions.

Definição Predefinido Description
MaxBatchSize 100 O número máximo de alterações processadas com cada iteração do loop de gatilho antes de serem enviadas para a função acionada.
PollingIntervalMs 1000 O atraso em milissegundos entre o processamento de cada lote de alterações. (1000 ms é 1 segundo)
MaxChangesPerWorker 1000 O limite superior do número de alterações pendentes na tabela do usuário permitidas por trabalhador do aplicativo. Se a contagem de alterações exceder esse limite, isso pode resultar em uma expansão. A configuração só se aplica aos Aplicativos de Função do Azure com o dimensionamento controlado por tempo de execução habilitado.

Exemplo de arquivo host.json

Aqui está um exemplo host.json arquivo com as configurações opcionais:

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

local.setting.json

O arquivo local.settings.json armazena as configurações do aplicativo e as configurações usadas pelas ferramentas de desenvolvimento local. As configurações no arquivo local.settings.json são usadas somente quando você está executando seu projeto localmente. Quando publicar o seu projeto no Azure, certifique-se de que também adiciona quaisquer definições necessárias às definições da aplicação para a aplicação de funções.

Importante

Como o local.settings.json pode conter segredos, como cadeias de conexão, você nunca deve armazená-lo em um repositório remoto. As ferramentas que suportam Funções fornecem maneiras de sincronizar as configurações no arquivo de local.settings.json com as configurações do aplicativo no aplicativo de função no qual seu projeto é implantado.

Definição Predefinido Description
Sql_Trigger_BatchSize 100 O número máximo de alterações processadas com cada iteração do loop de gatilho antes de serem enviadas para a função acionada.
Sql_Trigger_PollingIntervalMs 1000 O atraso em milissegundos entre o processamento de cada lote de alterações. (1000 ms é 1 segundo)
Sql_Trigger_MaxChangesPerWorker 1000 O limite superior do número de alterações pendentes na tabela do usuário permitidas por trabalhador do aplicativo. Se a contagem de alterações exceder esse limite, isso pode resultar em uma expansão. A configuração só se aplica aos Aplicativos de Função do Azure com o dimensionamento controlado por tempo de execução habilitado.

Exemplo local.settings.json arquivo

Aqui está um exemplo local.settings.json arquivo com as configurações opcionais:

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

Configurar o controlo de alterações (obrigatório)

Configurar o controle de alterações para uso com o gatilho SQL do Azure requer duas etapas. Essas etapas podem ser concluídas a partir de qualquer ferramenta SQL que ofereça suporte à execução de consultas, incluindo Visual Studio Code, Azure Data Studio ou SQL Server Management Studio.

  1. Habilite o controle de alterações no banco de dados SQL, substituindo your database name pelo nome do banco de dados onde a tabela a ser monitorada está localizada:

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

    A CHANGE_RETENTION opção especifica o período de tempo durante o qual as informações de controlo de alterações (histórico de alterações) são mantidas. A retenção do histórico de alterações pelo banco de dados SQL pode afetar a funcionalidade de gatilho. Por exemplo, se a Função do Azure for desativada por vários dias e depois retomada, o banco de dados conterá as alterações que ocorreram nos últimos dois dias no exemplo de configuração acima.

    A AUTO_CLEANUP opção é usada para habilitar ou desabilitar a tarefa de limpeza que remove informações antigas de controle de alterações. Se for um problema temporário que impeça a execução do gatilho, desativar a limpeza automática pode ser útil para pausar a remoção de informações anteriores ao período de retenção até que o problema seja resolvido.

    Mais informações sobre as opções de controle de alterações estão disponíveis na documentação do SQL.

  2. Habilite o controle de alterações na tabela, substituindo pelo nome da tabela a ser monitorada (alterando your table name o esquema, se apropriado):

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

    O gatilho precisa ter acesso de leitura na tabela que está sendo monitorada para alterações e para as tabelas do sistema de controle de alterações. Cada gatilho de função tem uma tabela de controle de alterações associada e uma tabela de concessões em um esquema az_func. Essas tabelas são criadas pelo gatilho se ainda não existirem. Mais informações sobre essas estruturas de dados estão disponíveis na documentação da biblioteca de vinculação SQL do Azure.

Habilite o dimensionamento controlado por tempo de execução

Opcionalmente, suas funções podem ser dimensionadas automaticamente com base no número de alterações pendentes para serem processadas na tabela do usuário. Para permitir que suas funções sejam dimensionadas corretamente no plano Premium ao usar gatilhos SQL, você precisa habilitar o monitoramento da escala de tempo de execução.

No portal do Azure, em seu aplicativo de função, escolha Configuração e, na guia Configurações de tempo de execução da função, ative o monitoramento da escala de tempo de execução.

Captura de tela do painel do portal do Azure para habilitar o dimensionamento em tempo de execução.

Suporte para repetir

Mais informações sobre o suporte a repetição de gatilho SQL e tabelas de concessões estão disponíveis no repositório GitHub.

Tentativas de inicialização novamente

Se ocorrer uma exceção durante a inicialização, o tempo de execução do host tentará reiniciar automaticamente o ouvinte de gatilho com uma estratégia de recuo exponencial. Essas novas tentativas continuam até que o ouvinte seja iniciado com êxito ou a inicialização seja cancelada.

Tentativas de conexão interrompida novamente

Se a função for iniciada com êxito, mas um erro fizer com que a conexão seja interrompida (como o servidor ficar offline), a função continuará a tentar reabrir a conexão até que a função seja interrompida ou a conexão seja bem-sucedida. Se a conexão for restabelecida com sucesso, ela retomará as alterações de processamento de onde parou.

Observe que essas novas tentativas estão fora da lógica de repetição de conexão ociosa interna que o SqlClient tem, que pode ser configurada com as ConnectRetryCount opções e ConnectRetryInterval cadeia de conexão. As novas tentativas de conexão ociosa interna são tentadas primeiro e, se não conseguirem se reconectar, a ligação de gatilho tenta restabelecer a própria conexão.

Repetição de exceção de função

Se ocorrer uma exceção na função de usuário durante o processamento de alterações, o lote de linhas que estão sendo processadas será repetido novamente em 60 segundos. Outras alterações são processadas normalmente durante esse tempo, mas as linhas no lote que causaram a exceção são ignoradas até que o período de tempo limite tenha decorrido.

Se a execução da função falhar cinco vezes seguidas para uma determinada linha, essa linha será completamente ignorada para todas as alterações futuras. Como as linhas em um lote não são determinísticas, as linhas em um lote com falha podem acabar em lotes diferentes em invocações subsequentes. Isso significa que nem todas as linhas do lote com falha serão necessariamente ignoradas. Se outras linhas no lote foram as que causaram a exceção, as linhas "boas" podem acabar em um lote diferente que não falha em invocações futuras.

Próximos passos