Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Uwaga
Mimo że powiązania danych wejściowych i wyjściowych są obsługiwane we wszystkich planach, powiązanie wyzwalacza usługi Azure Database for MySQL jest dostępne tylko w planach dedykowanych i premium w okresie obowiązywania wersji zapoznawczej.
Powiązania wyzwalacza usługi Azure Database for MySQL monitorują tabelę użytkowników pod kątem zmian (wstawień i aktualizacji) i wywołują funkcję ze zaktualizowanymi danymi wierszy.
Powiązania wyzwalacza usługi Azure Database for MySQL używają danych kolumn i służą az_func_updated_at
do monitorowania tabeli użytkowników pod kątem zmian. W związku z tym należy zmienić strukturę tabeli, aby umożliwić śledzenie zmian w tabeli MySQL przed użyciem obsługi wyzwalacza. Śledzenie zmian w tabeli można włączyć za pomocą następującego zapytania. Na przykład włącz ją w Products
tabeli:
ALTER TABLE Products
ADD az_func_updated_at TIMESTAMP DEFAULT
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Tabela dzierżaw zawiera wszystkie kolumny odpowiadające kluczowi podstawowemu z tabeli użytkownika i trzy kolejne kolumny: az_func_AttemptCount
, az_func_LeaseExpirationTime
i az_func_SyncCompletedTime
. Jeśli którakolwiek z kolumn klucza podstawowego ma taką samą nazwę, wynik jest komunikatem o błędzie, który wyświetla konflikty. W takim przypadku należy zmienić nazwę wymienionych kolumn klucza podstawowego, aby wyzwalacz działał.
Omówienie funkcji
Po uruchomieniu funkcji wyzwalacza inicjuje dwie oddzielne pętle: pętlę sondowania zmian i pętlę odnawiania dzierżawy. Pętle te są uruchamiane w sposób ciągły do momentu zatrzymania funkcji.
Powiązanie wyzwalacza usługi Azure Database for MySQL używa pętli sondowania do sprawdzania zmian. Pętla sondowania wyzwala funkcję użytkownika po wykryciu zmian. Na wysokim poziomie pętla wygląda następująco:
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
}
Zmiany są przetwarzane w kolejności ich wprowadzania. Najstarsze zmiany są najpierw przetwarzane. Rozważ następujące kwestie dotyczące przetwarzania zmian:
- Jeśli zmiany wystąpią w wielu wierszach jednocześnie, dokładna kolejność, w jakiej są wysyłane do funkcji, jest oparta na kolejności rosnącej
az_func_updated_at
kolumny i kolumn klucza podstawowego. - Zmiany są wsadowe dla wiersza. Jeśli wiele zmian wystąpi w wierszu między każdą iterację pętli, uwzględniany jest tylko najnowszy wpis zmiany, który istnieje dla tego wiersza.
Uwaga
Obecnie tożsamości zarządzane nie są obsługiwane w przypadku połączeń między usługami Azure Functions i Azure Database for MySQL.
Przykładowe użycie
Więcej przykładów dla wyzwalacza usługi Azure Database for MySQL jest dostępnych w repozytorium GitHub.
W przykładzie Product
odwołuje się do klasy i odpowiedniej tabeli bazy danych:
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
);
Śledzenie zmian w bazie danych można włączyć, dodając jedną kolumnę do tabeli:
ALTER TABLE <table name>
ADD COLUMN az_func_updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Wyzwalacz usługi Azure Database for MySQL wiąże się z IReadOnlyList<MySqlChange<T>>
elementem , który zawiera listę MySqlChange
obiektów. Każdy obiekt ma dwie właściwości:
-
Item
: element, który został zmieniony. Typ elementu powinien być zgodny ze schematem tabeli, jak pokazanoToDoItem
w klasie. -
Operation
: wartość zMySqlChangeOperation
wyliczenia. Możliwa wartość dotyczyUpdate
zarówno wstawiania, jak i aktualizacji.
W poniższym przykładzie pokazano funkcję języka C# , która jest wywoływana w przypadku wystąpienia zmian w Product
tabeli:
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);
}
}
}
Przykładowe użycie
Więcej przykładów dla wyzwalacza usługi Azure Database for MySQL jest dostępnych w repozytorium GitHub.
W przykładzie Product
odwołuje się do klasy, MySqlChangeProduct
klasy, MySqlChangeOperation
wyliczenia i odpowiedniej tabeli bazy danych.
W osobnym pliku o nazwie 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;
}
}
W osobnym pliku o nazwie 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;
}
}
W osobnym pliku o nazwie 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
);
Śledzenie zmian w bazie danych można włączyć, dodając następującą kolumnę do tabeli:
ALTER TABLE <table name>
ADD COLUMN az_func_updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Wyzwalacz usługi Azure Database for MySQL wiąże się z MySqlChangeProduct[]
elementem , który jest tablicą MySqlChangeProduct
obiektów. Każdy obiekt ma dwie właściwości:
-
item
: element, który został zmieniony. Typ elementu powinien być zgodny ze schematem tabeli, jak pokazanoProduct
w klasie. -
operation
: wartość zMySqlChangeOperation
wyliczenia. Możliwa wartość dotyczyUpdate
zarówno wstawiania, jak i aktualizacji.
W poniższym przykładzie przedstawiono funkcję Języka Java wywoływaną w przypadku wystąpienia zmian w Product
tabeli:
/**
* 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));
}
}
Przykładowe użycie
Więcej przykładów dla wyzwalacza usługi Azure Database for MySQL jest dostępnych w repozytorium GitHub.
W przykładzie Product
odwołuje się do tabeli bazy danych:
DROP TABLE IF EXISTS Products;
CREATE TABLE Products (
ProductId int PRIMARY KEY,
Name varchar(100) NULL,
Cost int NULL
);
Śledzenie zmian w bazie danych można włączyć, dodając jedną kolumnę do tabeli:
ALTER TABLE <table name>
ADD COLUMN az_func_updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Wyzwalacz usługi Azure Database for MySQL wiąże się z Product
elementem , który zawiera listę obiektów. Każdy obiekt ma dwie właściwości:
-
item
: element, który został zmieniony. Struktura elementu jest zgodna ze schematem tabeli. -
operation
: Możliwa wartość jestUpdate
zarówno dla wstawień, jak i aktualizacji.
W poniższym przykładzie przedstawiono funkcję programu PowerShell wywoływaną w przypadku wystąpienia zmian w Product
tabeli.
W poniższym przykładzie przedstawiono powiązanie danych w pliku function.json:
{
"bindings": [
{
"name": "changes",
"type": "mysqlTrigger",
"direction": "in",
"tableName": "Products",
"connectionStringSetting": "MySqlConnectionString"
}
],
"disabled": false
}
W sekcji Konfiguracja opisano te właściwości.
Poniższy przykład to przykładowy kod programu PowerShell dla funkcji w pliku run.ps1:
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"
Przykładowe użycie
Więcej przykładów dla wyzwalacza usługi Azure Database for MySQL jest dostępnych w repozytorium GitHub.
W przykładzie Product
odwołuje się do tabeli bazy danych:
DROP TABLE IF EXISTS Products;
CREATE TABLE Products (
ProductId int PRIMARY KEY,
Name varchar(100) NULL,
Cost int NULL
);
Śledzenie zmian w bazie danych można włączyć, dodając jedną kolumnę do tabeli:
ALTER TABLE <table name>
ADD COLUMN az_func_updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Wyzwalacz usługi Azure Database for MySQL wiąże się z Changes
elementem , który jest tablicą obiektów. Każdy obiekt ma dwie właściwości:
-
item
: element, który został zmieniony. Struktura elementu jest zgodna ze schematem tabeli. -
operation
: Możliwa wartość jestUpdate
zarówno dla wstawień, jak i aktualizacji.
W poniższym przykładzie przedstawiono funkcję języka JavaScript wywoływaną w przypadku wystąpienia zmian w Product
tabeli.
W poniższym przykładzie przedstawiono powiązanie danych w pliku function.json:
{
"bindings": [
{
"name": "changes",
"type": "mysqlTrigger",
"direction": "in",
"tableName": "Products",
"connectionStringSetting": "MySqlConnectionString",
}
],
"disabled": false
}
W sekcji Konfiguracja opisano te właściwości.
Poniższy przykład to przykładowy kod JavaScript dla funkcji w index.js
pliku :
module.exports = async function (context, changes) {
context.log(`MySql Changes: ${JSON.stringify(changes)}`)
}
Przykładowe użycie
Więcej przykładów dla wyzwalacza usługi Azure Database for MySQL jest dostępnych w repozytorium GitHub.
W przykładzie Product
odwołuje się do tabeli bazy danych:
DROP TABLE IF EXISTS Products;
CREATE TABLE Products (
ProductId int PRIMARY KEY,
Name varchar(100) NULL,
Cost int NULL
);
Śledzenie zmian w bazie danych można włączyć, dodając jedną kolumnę do tabeli:
ALTER TABLE <table name>
ADD COLUMN az_func_updated_at TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Uwaga
Musisz użyć usługi Azure Functions w wersji 1.22.0b4 dla języka Python.
Wyzwalacz usługi Azure Database for MySQL wiąże się ze zmienną o nazwie Product
, która wyświetla listę obiektów. Każdy obiekt ma dwie właściwości:
-
item
: element, który został zmieniony. Struktura elementu jest zgodna ze schematem tabeli. -
operation
: Możliwa wartość jestUpdate
zarówno dla wstawień, jak i aktualizacji.
W poniższym przykładzie przedstawiono funkcję języka Python wywoływaną w przypadku wystąpienia zmian w Product
tabeli.
Poniższy przykład to przykładowy kod języka Python dla pliku function_app.py:
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))
Atrybuty
Właściwość atrybutu | opis |
---|---|
TableName |
Wymagany. Nazwa tabeli monitora wyzwalacza. |
ConnectionStringSetting |
Wymagany. Nazwa ustawienia aplikacji zawierającego parametry połączenia dla bazy danych zawierającej tabelę monitorowaną pod kątem zmian. Nazwa ustawienia parametrów połączenia odpowiada ustawieniu aplikacji (w local.settings.json programowania lokalnego), które zawiera parametry połączenia z usługą Azure Database for MySQL. |
LeasesTableName |
Opcjonalny. Nazwa tabeli do przechowywania dzierżaw. Jeśli nie zostanie określony, nazwa to Leases_{FunctionId}_{TableId} . |
Adnotacje
W bibliotece środowiska uruchomieniowego funkcji Języka Java użyj @MySQLTrigger
adnotacji dotyczącej parametrów, których wartości pochodzą z usługi Azure Database for MySQL. Ta adnotacja obsługuje następujące elementy:
Składnik | opis |
---|---|
name |
Wymagany. Nazwa parametru powiązanego z wyzwalaczem. |
tableName |
Wymagany. Nazwa tabeli monitora wyzwalacza. |
connectionStringSetting |
Wymagany. Nazwa ustawienia aplikacji zawierającego parametry połączenia dla bazy danych zawierającej tabelę monitorowaną pod kątem zmian. Nazwa ustawienia parametrów połączenia odpowiada ustawieniu aplikacji (w local.settings.json programowania lokalnego), które zawiera parametry połączenia z usługą Azure Database for MySQL. |
LeasesTableName |
Opcjonalny. Nazwa tabeli do przechowywania dzierżaw. Jeśli nie zostanie określony, nazwa to Leases_{FunctionId}_{TableId} . |
Konfigurowanie
W poniższej tabeli opisano właściwości konfiguracji powiązania ustawione w pliku function.json:
Majątek | opis |
---|---|
name |
Wymagany. Nazwa parametru powiązanego z wyzwalaczem. |
type |
Wymagany. Musi być ustawiona wartość MysqlTrigger . |
direction |
Wymagany. Musi być ustawiona wartość in . |
tableName |
Wymagany. Nazwa tabeli monitora wyzwalacza. |
connectionStringSetting |
Wymagany. Nazwa ustawienia aplikacji zawierającego parametry połączenia dla bazy danych zawierającej tabelę monitorowaną pod kątem zmian. Nazwa ustawienia parametrów połączenia odpowiada ustawieniu aplikacji (w local.settings.json programowania lokalnego), które zawiera parametry połączenia z usługą Azure Database for MySQL. |
LeasesTableName |
Opcjonalny. Nazwa tabeli do przechowywania dzierżaw. Jeśli nie zostanie określony, nazwa to Leases_{FunctionId}_{TableId} . |
Opcjonalna konfiguracja
Możesz skonfigurować następujące opcjonalne ustawienia wyzwalacza usługi Azure Database for MySQL na potrzeby lokalnego programowania lub wdrożeń w chmurze.
host.json
W tej sekcji opisano ustawienia konfiguracji dostępne dla tego powiązania w wersji 2.x lub nowszej. Ustawienia w pliku host.json mają zastosowanie do wszystkich funkcji w wystąpieniu aplikacji funkcji. Aby uzyskać więcej informacji na temat ustawień konfiguracji aplikacji funkcji, zobacz host.json dokumentacja usługi Azure Functions.
Ustawienie | Domyślny | opis |
---|---|---|
MaxBatchSize |
100 |
Maksymalna liczba zmian przetworzonych przy każdej iteracji pętli wyzwalacza przed wysłaniem ich do wyzwalanej funkcji. |
PollingIntervalMs |
1000 |
Opóźnienie w milisekundach między przetwarzaniem każdej partii zmian. (1000 ms to 1 sekunda). |
MaxChangesPerWorker |
1000 |
Górny limit liczby oczekujących zmian w tabeli użytkowników dozwolonych dla procesu roboczego aplikacji. Jeśli liczba zmian przekroczy ten limit, może to spowodować zwiększenie skali w poziomie. To ustawienie dotyczy tylko aplikacji funkcji platformy Azure z włączonym skalowaniem opartym na środowisku uruchomieniowym. |
Przykładowy plik host.json
Oto przykładowy plik host.json z opcjonalnymi ustawieniami:
{
"version": "2.0",
"extensions": {
"MySql": {
"MaxBatchSize": 300,
"PollingIntervalMs": 1000,
"MaxChangesPerWorker": 100
}
},
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
},
"logLevel": {
"default": "Trace"
}
}
}
local.setting.json
Plik local.settings.json przechowuje ustawienia i ustawienia aplikacji używane przez lokalne narzędzia programistyczne. Ustawienia w pliku local.settings.json są używane tylko wtedy, gdy uruchamiasz projekt lokalnie. Podczas publikowania projektu na platformie Azure należy również dodać wszystkie wymagane ustawienia do ustawień aplikacji dla aplikacji funkcji.
Ważne
Ponieważ plik local.settings.json może zawierać wpisy tajne, takie jak parametry połączenia, nigdy nie należy przechowywać go w repozytorium zdalnym. Narzędzia, które obsługują usługę Azure Functions, zapewniają sposoby synchronizowania ustawień w pliku local.settings.json z ustawieniami aplikacji w aplikacji funkcji, do której wdrożono projekt.
Ustawienie | Domyślny | opis |
---|---|---|
MySql_Trigger_BatchSize |
100 |
Maksymalna liczba zmian przetworzonych przy każdej iteracji pętli wyzwalacza przed wysłaniem ich do wyzwalanej funkcji. |
MySql_Trigger_PollingIntervalMs |
1000 |
Opóźnienie w milisekundach między przetwarzaniem każdej partii zmian. (1000 ms to 1 sekunda). |
MySql_Trigger_MaxChangesPerWorker |
1000 |
Górny limit liczby oczekujących zmian w tabeli użytkowników dozwolonych dla procesu roboczego aplikacji. Jeśli liczba zmian przekroczy ten limit, może to spowodować zwiększenie skali w poziomie. To ustawienie dotyczy tylko aplikacji funkcji platformy Azure z włączonym skalowaniem opartym na środowisku uruchomieniowym. |
Przykładowy plik local.settings.json
Oto przykładowy plik local.settings.json z opcjonalnymi ustawieniami:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"MySqlConnectionString": "",
"MySql_Trigger_MaxBatchSize": 300,
"MySql_Trigger_PollingIntervalMs": 1000,
"MySql_Trigger_MaxChangesPerWorker": 100
}
}
Konfigurowanie śledzenia zmian (wymagane)
Skonfigurowanie śledzenia zmian do użycia z wyzwalaczem usługi Azure Database for MySQL wymaga dodania kolumny w tabeli przy użyciu funkcji. Te kroki można wykonać za pomocą dowolnego narzędzia MySQL, które obsługuje uruchamianie zapytań, w tym programu Visual Studio Code lub narzędzia Azure Data Studio.
Powiązania wyzwalacza usługi Azure Database for MySQL używają danych kolumn i służą az_func_updated_at
do monitorowania tabeli użytkowników pod kątem zmian. W związku z tym należy zmienić strukturę tabeli, aby umożliwić śledzenie zmian w tabeli MySQL przed użyciem obsługi wyzwalacza. Śledzenie zmian w tabeli można włączyć za pomocą następującego zapytania. Na przykład włącz ją w Products
tabeli:
ALTER TABLE Products;
ADD az_func_updated_at
TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Tabela dzierżaw zawiera wszystkie kolumny odpowiadające kluczowi podstawowemu z tabeli użytkownika i dwie kolejne kolumny: az_func_AttemptCount
i az_func_LeaseExpirationTime
. Jeśli którakolwiek z kolumn klucza podstawowego ma taką samą nazwę, wynik jest komunikatem o błędzie, który wyświetla konflikty. W takim przypadku należy zmienić nazwę wymienionych kolumn klucza podstawowego, aby wyzwalacz działał.
Włączanie skalowania opartego na środowisku uruchomieniowym
Opcjonalnie funkcje mogą być skalowane automatycznie na podstawie liczby zmian oczekujących na przetworzenie w tabeli użytkowników. Aby umożliwić prawidłowe skalowanie funkcji w planie Premium podczas korzystania z wyzwalaczy usługi Azure Database for MySQL, należy włączyć monitorowanie skalowania w czasie wykonywania.
W witrynie Azure Portal w aplikacji funkcji wybierz pozycję Konfiguracja.
Na karcie Ustawienia środowiska uruchomieniowego funkcji w obszarze Monitorowanie skalowania środowiska uruchomieniowego wybierz pozycję Włączone.
Pomoc techniczna dotycząca ponawiania prób
Ponowne próby uruchamiania
Jeśli podczas uruchamiania wystąpi wyjątek, środowisko uruchomieniowe hosta automatycznie podejmie próbę ponownego uruchomienia odbiornika wyzwalacza ze strategią wycofywania wykładniczego. Te próby będą kontynuowane do momentu pomyślnego uruchomienia odbiornika lub anulowania uruchamiania.
Ponowne próby wyjątku funkcji
Jeśli wystąpi wyjątek w funkcji użytkownika podczas przetwarzania zmian, partia obecnie przetwarzanych wierszy zostanie ponowiona w ciągu 60 sekund. Inne zmiany są przetwarzane normalnie w tym czasie, ale wiersze w partii, które spowodowały wyjątek, są ignorowane do czasu upływu limitu czasu.
Jeśli wykonanie funkcji zakończy się niepowodzeniem pięć kolejnych razy dla określonego wiersza, ten wiersz zostanie zignorowany dla wszystkich przyszłych zmian. Ponieważ wiersze w partii nie są deterministyczne, wiersze w partii zakończone niepowodzeniem mogą skończyć się w różnych partiach w kolejnych wywołaniach. To zachowanie oznacza, że nie wszystkie wiersze w partii, które zakończyły się niepowodzeniem, muszą być ignorowane. Jeśli inne wiersze w partii spowodowały wyjątek, wiersze "dobre" mogą skończyć się w innej partii, która nie zakończy się niepowodzeniem w przyszłych wywołaniach.