错误处理和补偿
在 Durable Task Framework 中进行错误处理和补偿
https://github.com/Azure/durabletask/wiki/Error-Handling-&-Compensation
在 TaskActivity 代码中抛出的任何异常都会在 TaskOrchestration 代码中以 TaskFailedException 的形式回调和抛出。用户可以根据自己的需要编写适当的错误处理和补偿代码。
public class DebitCreditOrchestration :
TaskOrchestration<object, DebitCreditOperation>
{
public override async Task<object> RunTask(OrchestrationContext context,
DebitCreditOperation operation)
{
bool failed = false;
bool debited = false;
try
{
await context.ScheduleTask<object>(typeof (DebitAccount),
new Tuple<string, float>(operation.SourceAccount, operation.Amount));
debited = true;
await context.ScheduleTask<object>(typeof(CreditAccount),
new Tuple<string, float>(operation.TargetAccount, operation.Amount));
}
catch (TaskFailedException exception)
{
if (debited)
{
// can build a try-catch around this as well, in which case the
// orchestration may either retry a few times or log the inconsistency for review
await context.ScheduleTask<object>(typeof(CreditAccount),
new Tuple<string, float>(operation.SourceAccount, operation.Amount));
}
}
return null;
}
}
请注意,在 dotnet 6.0 之前,由于 CLR 的限制,不能在 catch 块中使用 await 关键字。在这种情况下,我们可以修改上面的代码,设置一个失败标志,并在返回结果前执行补偿:
# ... orchestration code here
catch (TaskFailedException exception)
{
failed = true;
}
if (failed)
{
if (debited)
{
// can build a try-catch around this as well, in which case the
// orchestration may either retry a few times or log the inconsistency for review
await context.ScheduleTask<object>(typeof(CreditAccount),
new Tuple<string, float>(operation.SourceAccount, operation.Amount));
}
}
return null;
}
}