| 123456789101112131415161718192021222324252627282930313233343536373839 |
- using MySqlConnector;
- namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
- /// <summary>
- /// 库存标准层物化 SQL 的死锁重试。只重试 MySQL 1213 / 1205,最多 3 次。
- /// </summary>
- public static class InventoryMaterializationRetry
- {
- public const int MaxAttempts = 3;
- public static readonly int[] RetryDelayMilliseconds = [250, 750];
- public static bool IsRetryable(Exception ex)
- {
- for (var current = ex; current != null; current = current.InnerException)
- {
- if (current is MySqlException mysql && (mysql.Number == 1213 || mysql.Number == 1205))
- return true;
- }
- return false;
- }
- public static async Task<T> ExecuteAsync<T>(Func<Task<T>> action, CancellationToken cancellationToken = default)
- {
- if (action == null) throw new ArgumentNullException(nameof(action));
- for (var attempt = 1; ; attempt++)
- {
- cancellationToken.ThrowIfCancellationRequested();
- try
- {
- return await action();
- }
- catch (Exception ex) when (IsRetryable(ex) && attempt < MaxAttempts)
- {
- await Task.Delay(RetryDelayMilliseconds[attempt - 1], cancellationToken);
- }
- }
- }
- }
|